我正在開發一個使用3個模塊提供打印,捕獲和觸發功能的照片展位應用程序。這個想法是人們可以爲它開發擴展這個功能的模塊。這些模塊被實現爲共享庫,當用戶點擊「開始」時,這些共享庫在運行時加載。在運行時加載的共享庫中的Libcurl和curl_global_init
我想實現一個「打印」到Facebook圖片庫的打印機模塊。我想爲此使用libcurl。我的問題是初始化函數:curl_global_init()
libcurl API文檔指出,此函數絕對不是線程安全的。從the docs:
此函數不是線程安全的。當程序中的任何其他線程(即共享相同內存的線程)正在運行時,您不得調用它。這並不意味着沒有其他使用libcurl的線程。由於curl_global_init()調用類似線程不安全的其他庫的函數,因此它可能會與使用這些其他庫的其他線程發生衝突。
Elsewhere的文檔中,它說:
當你正在編寫使用libcurl的代碼不是主程序,而是一個模塊化一塊程序的全局常量局勢值得特別考慮,例如另一個庫。作爲一個模塊,你的代碼不知道程序的其他部分 - 它不知道他們是否使用libcurl。它的代碼不一定會在整個程序的開始和結束時運行。
像這樣的模塊必須具有自己的全局常量函數,就像curl_global_init()和curl_global_cleanup()一樣。模塊因此在程序的開始和結束時都有控制權,並且有一個地方可以調用libcurl函數。
......這似乎解決了這個問題。但是,這似乎意味着我的模塊的init()
和finalize()
函數將在程序的開始和結束處被調用。由於模塊設計爲在運行時可以交換,所以我無法做到這一點。就算我想到了,我的應用程序使用的GLib,這佔其documentation,這是從來沒有安全的假設沒有運行的線程:
...從版本2.32,GLib的線程系統會自動在啓動初始化的程序,並且所有線程創建函數和同步原語都可以立即使用。
請注意,即使您自己不調用g_thread_new(),也不安全地假定程序沒有線程。 GLib和GIO可以並且將爲他們自己的目的創建線程...
我的問題是:有什麼方法可以在我的應用程序中安全地調用curl_global_init()
?我可以將電話curl_global_init()
和curl_global_cleanup()
放在我的模塊的init()
和finalize()
功能中嗎?我是否需要找到另一個HTTP庫?
感謝您的回覆。我一直在考慮從我的模塊中派生一個流程,並讓其子流程出於其他原因處理實際工作,但是我決定採取一種更簡單的解決方案。但是,在我看來,這可能是解決此問題最安全的方法。 – Chris
@Chris請注意,如果您在多線程程序中使用fork(),則在成功執行execve()之前,不得調用任何異步信號不安全的函數(即,幾乎任何內容)。您需要創建一個單獨的exectuable。 – Demi