簡體   English   中英

Libcurl和curl_global_init在運行時加載的共享庫中

[英]Libcurl and curl_global_init in shared library loaded at runtime

我正在開發一個照相亭應用程序,它使用3個模塊來提供打印,捕獲和觸發功能。 我們的想法是人們可以為它開發擴展此功能的模塊。 這些模塊實現為共享庫,在用戶單擊“開始”時在運行時加載。

我正在嘗試實現一個“打印”到Facebook圖庫的打印機模塊。 我想為此使用libcurl。 我的問題在於初始化函數: curl_global_init() libcurl API文檔聲明此函數絕對不是線程安全的。 來自文檔

此功能不是線程安全的。 當程序中的任何其他線程(即共享相同內存的線程)正在運行時,您不能調用它。 這並不僅僅意味着沒有其他使用libcurl的線程。 因為curl_global_init()調用類似線程不安全的其他庫的函數,所以它可能與使用這些其他庫的任何其他線程沖突。

在文檔的其他地方 ,它說:

當您編寫使用libcurl的代碼不是主程序時,全局常量情況值得特別考慮,而是程序的模塊化部分,例如另一個庫。 作為一個模塊,你的代碼不知道程序的其他部分 - 它不知道它們是否使用libcurl。 它的代碼不一定在整個程序的開始和結束時運行。

像這樣的模塊必須具有自己的全局常量函數,就像curl_global_init()和curl_global_cleanup()一樣。 因此,模塊在程序的開頭和結尾具有控制權,並且可以調用libcurl函數。

......這似乎解決了這個問題。 但是,這似乎意味着我的模塊的init()finalize()函數將在程序的開始和結束時調用。 由於模塊設計為在運行時可以交換,因此我無法做到這一點。 即使我可以,我的應用程序使用GLib,根據他們的文檔 ,假設沒有運行的線程是絕對安全的:

...從版本2.32開始,GLib線程系統在程序開始時自動初始化,並且所有線程創建函數和同步原語都可以立即使用。

請注意,即使您沒有自己調用g_thread_new(),也不能安全地假設您的程序沒有線程。 GLib和GIO可以並且將為自己的目的創建線程......

我的問題是:有沒有辦法在我的應用程序中安全地調用curl_global_init() 我可以在我的模塊的init()finalize()函數中調用curl_global_init()curl_global_cleanup()嗎? 我需要找到另一個HTTP庫嗎?

首先,如果沒有這些限制,您將找不到任何其他庫,因為它們是由具有這些限制的第三方(主要是SSL)庫中的libcurl繼承的。 例如OpenSSL。

這就是說,global_init的線程安全情況非常不幸,而且我們(在curl項目中)非常不喜歡,但只要我們使用其他庫,就無法做很多事情。 這也意味着您的確切情況取決於您的libcurl構建使用的確切依賴庫。

在大多數情況下,您可以按照建議的方式從模塊init()函數調用curl_global_init()。 我無法保證這是安全的,當然有100%的確定性,因為這里有一些我不能說的未知數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM