Home php c# sql c c++ javascript python java go android git linux asp.net django .net node.js ios xcode cocoa iphone mysql tomcat mongodb bash objective-c scala visual-studio apache elasticsearch jar eclipse jquery ruby-on-rails ruby rubygems android-studio spring lua sqlite emacs ubuntu perl docker swift amazon-web-services svn html ajax xml java-ee maven intellij-idea rvm macos unix css ipad postgresql css3 json windows-server vue.js typescript oracle hibernate internet-explorer github tensorflow laravel symfony redis html5 google-app-engine nginx firefox sqlalchemy lucene erlang flask vim solr webview facebook zend-framework virtualenv nosql ide twitter safari flutter bundle phonegap centos Register | Login | Edit Tags | New Questions | 繁体 | 简体


10 questions online user: 25

0
votes
answers
41 views
+10

如何啓動一個運行類函數的boost線程?

1

即時做一個C++類在內部,我想創建一個線程來執行類的功能,我該怎麼做?我給你看一些代碼。如何啓動一個運行類函數的boost線程?

成員函數我想在一個線程中運行:

void SocketServer::runServer(){ 
    bool connected; 
    tcp::acceptor a(io_service, tcp::endpoint(tcp::v4(), puerto)); 
    std::string data; 

    while(seguirFuncionando()){ 
     miSocket = new tcp::socket(io_service); 
     std::cout << "Waiting for connection...
"; 
     a.accept(*miSocket); 
     std::cout << "Connected
"; 
     connected = true; 
     try{ 
      while (connected){ 
       data = readStr(); 
       if (data.compare("")==0){ 
        std::cout << "End of connection.
"; 
       } 
       else{ 
        std::cout << data << "
"; 
       } 
      } 
     } 
     catch (std::exception& e){ 
     std::cerr << "Exception in thread: " << e.what() << "
"; 
     } 
    } 
} 

什麼我嘗試做:

void SocketServer::runThreadServer(){ 
    asio::thread t(runServer); 
} 

但它不編譯。錯誤:

沒有匹配函數調用'asio :: thread :: thread() 注意:候選是:asio :: thread :: thread(Function)[with Function = void(SocketServer :: *)( )]

我該怎麼做?

Thanx。

+1

你可能想嘗試用[boost.bind(http://www.boost.org/doc/libs/1_48_0/libs/bind/bind.html) – 2012-02-10 17:27:43

+0

@JoachimPileborg你能舉個例子嗎?即時通訊新的提振,而我有點失落:P – Alex 2012-02-10 17:29:25

沙发
0
4

像Joachim Pileborg說的,標準的做法是使用boost::bindboost::bind專門從C++對象及其成員函數構造一個名爲boost::function(可能在boost::thread的c'tor中傳遞)的構造。

事情是這樣的:

boost::thread t(boost::bind(&SocketServer::runServer, this)); 
+0

Thanx,這工作得很好:) Thanx valdo和Joachim。另一件事,我可以在哪裏學習如何提升Threads和Asio?我開發了一個客戶端 - 服務器應用程序,我需要處理得很好,但官方文檔不是很廣泛。我在哪裏可以得到很好的例子? Thanx – Alex 2012-02-10 17:41:30

+0

準確地說,'boost :: bind'不會創建'boost :: function'對象,它會創建* unknown *(無文檔,可以隨時更改)類型的對象,該類型可以分配給'boost ::功能「的適當簽名。 – 2012-02-10 17:45:46

0
votes
answers
10 views
+10

C++ boost ::線程,如何啓動線程內的線程

6

如何在對象內啓動線程?例如,C++ boost ::線程,如何啓動線程內的線程

class ABC 
{ 
public: 
void Start(); 
double x; 
boost::thread m_thread; 
}; 

ABC abc; 
... do something here ... 
... how can I start the thread with Start() function?, ... 
... e.g., abc.m_thread = boost::thread(&abc.Start()); ... 

這樣,以後我可以這樣做,

abc.thread.interrupt(); 
abc.thread.join(); 

感謝。

沙发
0
6

使用boost.bind:

boost::thread(boost::bind(&ABC::Start, abc)); 

你可能需要一個指針(或一個shared_ptr):

boost::thread* m_thread; 
m_thread = new boost::thread(boost::bind(&ABC::Start, abc)); 
+0

謝謝蓋伊,它工作得很好。 – 2607 2012-02-26 23:50:26

板凳
0
15

你既不需要綁定,也不指針。

boost::thread m_thread; 
//... 
m_thread = boost::thread(&ABC::Start, abc); 
+0

+1:你說得對。有一個參數相當於使用綁定的構造函數。我更喜歡綁定,因爲我發現它更具可讀性。還有支持移動線程,我想我喜歡指針,因爲我知道發生了什麼(複製與移動),但希望一切都朝着移動... – 2012-02-27 21:26:59

+0

這應該是接受的答案 – user463035818 2017-06-01 14:08:43

0
votes
answers
6 views
+10

如何睡覺一個C++ Boost線程

34

似乎不可能睡覺使用boost :: thread的線程。 方法睡眠需要system_time,但我該如何構建它?如何睡覺一個C++ Boost線程

尋找內庫並不能真正幫助很大......

基本上我有我傳遞給這個線程作爲入口點函數中的一個線程 ,我想打電話給像

boost::this_thread::sleep 

什麼的,該怎麼做?

謝謝

沙发
0
83

根據您的Boost版本:

要麼...

#include <boost/chrono.hpp> 
#include <boost/thread/thread.hpp> 

boost::this_thread::sleep_for(boost::chrono::milliseconds(100)); 

或者......

#include <boost/date_time/posix_time/posix_time.hpp> 
#include <boost/thread/thread.hpp> 

boost::this_thread::sleep(boost::posix_time::milliseconds(100)); 

您還可以使用微秒,秒,幾分鐘,幾小時,也許還有一些,我不確定。

+2

是的,謝謝你...我沒有注意使用this_thread,但只是提升::線程和沒有工作:) Thansk – Andry 2010-11-24 13:37:47

+2

這給了我以下錯誤(使用Xcode 5/LLVM):錯誤:沒有可行的轉換從'boost :: posix_time :: microseconds'(又名'subsecond_duration ')到'const system_time'(又名'const boost :: posix_time :: ptime') – 2014-01-31 11:38:15

板凳
0
3

首先

boost::posix_time::seconds secTime(1); 
boost::this_thread::sleep(secTime); 

其次

boost::this_thread::sleep(boost::posix_time::milliseconds(100)); 
地板
0
19

從另一篇文章,我學到boost::this_thread::sleep已經廢棄了升壓V1.5.3:http://www.boost.org/doc/libs/1_53_0/doc/html/thread/thread_management.html

相反,嘗試

void sleep_for(const chrono::duration<Rep, Period>& rel_time); 

例如

boost::this_thread::sleep_for(boost::chrono::seconds(60)); 

也許嘗試

void sleep_until(const chrono::time_point<Clock, Duration>& abs_time); 

我使用升壓V1.53與過時sleep功能,並不定期地崩潰的程序。當我將sleep函數的調用更改爲調用sleep_for函數時,程序停止崩潰。

4楼
0
0

我學到了艱辛的道路,至少在MS Visual Studio中(試過2013年和2015年)有

boost::this_thread::sleep(boost::posix_time::microseconds(SmallIterval)); 

boost::this_thread::sleep_for(boost::chrono::microseconds(SmallIterval)); 
or 
std::this_thread::sleep_for(std::chrono::microseconds(SmallIterval)); 

當間隔小於一些比較小的之間的巨大差異實質性的門檻(我看到15000微秒的閾值= 15毫秒)。

如果SmallIterval很小,sleep()會立即中斷。睡眠(100 mks)表現爲睡眠(0 mks)。

但是,小於閾值的時間間隔的sleep_for()在整個閾值內暫停。 sleep_for(100 mks)表現爲sleep_for(15000 mks)。

間隔大於閾值和值爲0的行爲是相同的。

0
votes
answers
6 views
+10

boost :: asio內部線程

3

當使用boost :: asio進行一些異步TCP通信時,我注意到它啓動了很多(3-4)內部線程。在the documentation閱讀,它說boost :: asio內部線程

"The implementation of this library for a particular platform may 
make use of one or more internal threads to emulate asynchronicity" 

現在我的lib有着嚴格的要求,以不啓動任何額外的線程(除了由客戶提供的,現在它也開始io_service::run()一個)。有沒有什麼辦法可以停止boost :: asio來創建這些額外的線程?

另外,是否有任何其他的異步庫,只能在一個線程中運行?

沙发
0
5

您可以通過在相應的轉換單位中定義BOOST_ASIO_DISABLE_THREADS來禁用仿真的異步操作支持。 The documentation有這樣說的定義

Explicitly disables Boost.Asio's threading support, independent of whether or not Boost as a whole supports threads.

如果你沒有找到platform specific implementation notes,它明確指出哪些操作使用該仿真。例如我幾乎在每個平臺上都知道async_resolve()是以這種方式模擬的,線程是在第一次調用async_resolve()時創建的。一些(所有?)Windows平臺模擬其他幾個操作,例如deadline_timer操作。

禁用線程支持的一種替代方法可能是避免這些模擬操作。我個人沒有在項目中使用BOOST_ASIO_DISABLE_THREADS,所以我不確定它是否有其他副作用。

+2

當定義了'BOOST_ASIO_DISABLE_THREADS'時,Asio在嘗試產生一個線程時拋出'boost :: asio :: error :: operation_not_supported'錯誤。因此,唯一的選擇是避免線程產卵操作。在大多數實現中,這可以通過使用'resolve()'而不是'async_resolve()'來完成。在Windows上,定義'BOOST_ASIO_DISABLE_IOCP'將導致Asio使用基於選擇的實現,該實現比較慢,但不應該產生額外的線程。 – 2013-02-20 16:01:00

+0

謝謝,實際上我根本沒有找到這個文檔。我將嘗試使用DISABLE_IOCP – Rolle 2013-02-20 16:05:56

板凳
0
1

您是否真的測試過它,以查看線程是否在您的特定平臺上生成?如果沒有,問題解決!如果有的話,你可能會考慮像libevent或libev這樣的不同的圖書館。無論是那些,還是由像Qt這樣的各種庫提供的一大堆其他異步事件循環都可以工作。

+0

是的,我看到他們產卵。此外,這個lib被移植到許多平臺 – Rolle 2013-02-20 15:01:58

0
votes
answers
6 views
+10

Boost線程取消

7

您可以像pthread一樣取消一個Boost線程嗎?Boost線程取消

我正在寫一個簡單的看門狗來終止工作線程,如果他們崩潰,並且似乎沒有辦法簡單地取消Boost線程庫中的線程。

沙发
0
10

他們不支持取消,這是一件好事,因爲它會引起各種微妙的問題。

看看文檔中涵蓋線程中斷和boost :: thread_interrupted異常的部分,並且提供一些可以讓你在清理東西的同時完成你想要的東西。

+0

看來像增加線程中斷不會幫助你,如果線程卡在一個循環,這是我試圖防範的事情之一。當我放棄可移植性時,我開始認爲我最好使用pthread清理處理程序。 – 2009-06-25 21:15:54

板凳
0
2

它們不支持取消開箱即用(如指出),但是這取決於你的處理工作線程(S)中的想法,我會考慮使用boost::condition通知線程它應該儘早完成(乾淨)。

0
votes
answers
6 views
+10

C++ Boost由於CPU類型,多線程比單線程慢?

2

我曾經發布過一些boost多線程。這一次我只是好奇和失望,因爲我認爲多線程應該比單一線程更快。C++ Boost由於CPU類型,多線程比單線程慢?

兩個線程文件I/O讀取/解析CSV數據。當我使用多線程時,每臺機器PENTIUM D CPU從DELL DESKTOP OPTILEX 745平均花費約40秒。

單線程,平均花費大約8-10秒。

我曾試圖從這些兩個線程使用完全不同的參數的名字,結果是沒有什麼不同。如果有人曾經使用C++ boost多線程讀取大數據文件和解析之前,我很想聽聽你的意見。謝謝。 Andrew

沙发
0
4

兩個線程是FILE I/O讀取/解析CSV數據。

如果他們正在讀取具有相同文件句柄的相同文件,那麼他們可能會花費大部分時間阻止等待另一個線程完成。如果他們使用不同的文件句柄來讀取同一個文件,他們會迫使磁盤繼續前後查找,這不如直接順序讀取那樣有效。

線程不會加速大文件讀取和解析。它所做的是讓你在文件被讀取和解析時完全做其他事情。

您已經創建了一個I/O瓶頸,這線程不會幫助。當算法可以分解爲獨立的執行線程時,線程用於減少CPU瓶頸;對以前輸出有很大依賴性的算法(文件解析是一種情況)通常不太好。

如果你能拆分解析問題,讓每個線程解析該文件的不同部分,你可能會得到一點點改善,但可能不會因爲追求會浪費你的時間。如果你可以有一個線程進行批量讀取和一些預處理,然後將塊移交給線程池以進行真正的繁重處理(還有其他什麼?),那麼你可能會看到比單線程有明顯改進。

這是所有普通和位流的意識,但很難做到跟你要提供的更多。我希望它有幫助。

+0

你們倆都給了我很棒的評論和建議。我不會接受你們任何一個的公平答案。我會盡量考慮如何根據你們的建議來改進我的多線程。僅供參考,兩個線程讀取不同文件相同的目錄。謝謝,邁克。 – AndrewS 2011-05-21 05:21:39

0
votes
answers
6 views
+10

Boost線程泄漏C++

17

有人能讓我知道boost線程庫是否泄漏。在我看來,它確實: 谷歌說我應該使用boost線程和pthread來編譯我正在做的,而在版本1.40中這個問題已經解決了,但是我仍然有漏洞。請注意,這將編譯得很好,但會檢測到泄漏。Boost線程泄漏C++

#include <boost/thread.hpp> 
#include <boost/date_time.hpp> 

void t1(){} 

int main(void){ 
boost::thread th1(t1); 
th1.join(); 
return 1; 
} 

隨着Valgrind的我得到以下輸出

HEAP SUMMARY: 
==8209==  in use at exit: 8 bytes in 1 blocks 
==8209== total heap usage: 5 allocs, 4 frees, 388 bytes allocated 
==8209== 
==8209== 8 bytes in 1 blocks are still reachable in loss record 1 of 1 
==8209== at 0x4024F20: malloc (vg_replace_malloc.c:236) 
==8209== by 0x4038CCB: boost::detail::get_once_per_thread_epoch() (in /usr/local/lib/libboost_thread.so.1.42.0) 
==8209== by 0x40329D4: ??? (in /usr/local/lib/libboost_thread.so.1.42.0) 
==8209== by 0x4032B26: boost::detail::get_current_thread_data() (in /usr/local/lib/libboost_thread.so.1.42.0) 
==8209== by 0x4033F32: boost::thread::join() (in /usr/local/lib/libboost_thread.so.1.42.0) 
==8209== by 0x804E7C3: main (testboost.cpp) 
==8209== 
==8209== LEAK SUMMARY: 
==8209== definitely lost: 0 bytes in 0 blocks 
==8209== indirectly lost: 0 bytes in 0 blocks 
==8209==  possibly lost: 0 bytes in 0 blocks 
==8209== still reachable: 8 bytes in 1 blocks 
==8209==   suppressed: 0 bytes in 0 blocks 

我也試圖與在以下網站上列出的代碼:http://antonym.org/2009/05/threading-with-boost---part-i-creating-threads.html 還是同樣的問題。

+0

看看boost源文件中的src/pthread/Once.cpp。很明顯,它不會泄漏(只需查找它使用的pthread庫函數的定義)。 – Mankarse 2011-06-12 11:23:22

+0

使用'std :: thread'而不是boost,代碼甚至不會運行;它終止於一個'std :: system_error'異常。 – 2011-06-12 11:41:04

+0

只是嘗試在上面的鏈接代碼,你最有可能會看到valgrind – 2011-06-12 18:32:11

沙发
0
10

這與升級1_46_1有關,因此它可能不適用於您正在使用的版本。如果你真的想說服自己,請看助推源。 (當我運行您的示例代碼時,OSX上的泄漏檢測器未檢測到任何泄漏)。

這不是一個實際的泄漏(除非pthreads,您使用的過時版本的boost或您的編譯器存在缺陷)。

get_once_per_thread_epoch mallocs一個新的uintmax_t並映射到線程本地存儲與epoch_tss_key有一個相關的析構函數釋放映射的數據。因此,malloced內存保證被釋放。

我真的不明白爲什麼valgrind會將此檢測爲泄漏,但可能是因爲pthread退出函數在valgrind函數之後的某個點執行。另一種可能是pthread函數本身在泄漏,但我沒有在文檔中看到任何暗示這種情況的東西。

+0

謝謝。我升級到1.46.1和valgrind發生同樣的錯誤。直接使用pthread編碼不會導致此錯誤。必須像你說的那樣,Valgrind可以檢測到線程的清潔 – 2011-06-12 18:33:46

0
votes
answers
6 views
+10

鏈接boost ::線程

3

我試圖學習與boost庫的東西,但當我嘗試編譯包含boost :: threads的東西時遇到問題。 我鏈接過程中得到一個錯誤,這就是消息:鏈接boost ::線程

/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lboost-thread 

但它的奇怪,因爲這種情況,只有當我與一個普通用戶編寫,使用根我也沒有問題編譯。

在此先感謝。

+1

你跑的命令是什麼?通常你必須在那裏提供'-L [/ path/to/boost]',所以它知道在哪裏找到它。 – 2012-03-05 20:57:26

+0

最近版本的boost需要使用「-lboost_thread」 – dsign 2012-03-05 21:19:28

+0

這是我運行的命令: g ++ -L/usr/local/boost_1_48_0/stage/lib -lboost-thread threadBoost.cpp,但它只能用於根目錄 – alkz 2012-03-05 23:12:32

沙发
0
1

檢查的lib名提升安裝路徑(默認是:/ usr/lib中/),如果是libboost_thread.so,加-lboost_thread。不要忘記用-L/usr/lib/boost指定升級目錄的路徑。 如果只是上班根,請檢查您的權限在此目錄中:

ls -la /usr/lib/ | grep boost 

你應該看到您的登錄,並rw_r_ [R _(檢查是否具有讀取權限)。

如果您對目錄和升壓LIB此權限,用gcc鏈接可以做到:

g++ obj.o obj2.o -L/usr/lib -lboost_thread 

,如果你沒有自己的文件或沒有讀取權限,以root身份登錄並將它們添加

chown -R /usr/lib <your login> 
chmod +r /usr/lib/lib*.so 
+1

我已經檢查的權限,但也有0K(777),我編譯如下: G ++ -L在/ usr /本地/ boost_1_48_0 /臺/ lib目錄-lboost線程threadBoost.cpp 但我仍然得到: 找不到 - LBOOST線程 – alkz 2012-03-06 12:28:20

板凳
0
0

添加/ path/to/boost到您的makefile庫包含路徑並且您的錯誤將消失。

另一種選擇是包括提升到您的LIBPATH變量

地板
0
5

包括

#include <boost/thread/thread.hpp> 

其它鏈接器標記

-lboost_system -lboost_thread-mt 
0
votes
answers
6 views
+10

C++提升線程重用線程

2

我試圖完成這樣的事情:C++提升線程重用線程

thread t; // create/initialize thread 
t.launch(); // launch thread. 
t.wait(); // wait 
t.launch(); // relaunch the same thread 

如何去實現這樣的使用boost線程?本質上,我需要持久的可重新啓動的線程。

我想,以避免工作隊列,因爲在我的情況下實現有一定的困難

感謝

沙发
0
4

你只想讓線程運行在一個循環。它試圖從隊列中取出一部分「工作」,執行工作,然後返回隊列。當隊列爲空時,它等待。

然後從另一個線程中,您可以插入工作項到隊列中,以便線程執行它們。

再次讀你的問題,你是說你想讓你的主線程通知工作線程開始工作,但主線程必須立即開始等待工作完成?這意味着一次只能運行一個線程。這是沒有意義的。線程是爲併發執行而設計的。

假設這不是你想要的,那麼我想知道什麼比簡單的工作線程跑出隊列更簡單。線程正在工作或等待。因此,您需要一些允許主人和工人之間進行通信的數據結構,以便工作人員可以等待工作物件到達,並且主人可以發送工作物件,以喚醒工作人員,然後在工作物件完成時,工人等待另一個。

+0

這是另一種選擇。 但是在我的情況下,工作隊列有點複雜。如果我有主線程分配工作(這是我正在嘗試做的),它會簡單得多 – Anycorn 2010-04-17 16:25:06

+0

@aaa - 請參閱update;除非你完全擺脫線程,否則我看不出如何做比這更簡單的事情。 – 2010-04-17 16:35:53

+0

工作結構是一個帶有奇怪邊界的嵌套循環,並非所有線程都可以處理所有工作。然而,我確實設法實施了積壓的平面任務隊列。這可能是更可擴展的方法 – Anycorn 2010-04-18 01:34:56

0
votes
answers
6 views
+10

如何重新啓動提升截止日期計時器

0

我有一個要求,我的計時器必須根據2個條件進行重置,以先發生者爲準。如何重新啓動提升截止日期計時器

  1. 當計時器到期
  2. 當滿足特定條件(如內存達到某一限度)

我以下步驟:

boost::asio::io_service io; 
boost::asio::deadline_timer t(io, boost::posix_time::seconds(1)); 
boost::mutex mtx1; 

void run_io_service() 
{ 
    io.run(); 
} 

void print(const boost::system::error_code& /*e*/) 
{ 
    boost::mutex::scoped_lock lock(mtx1); 
    std::cout << "Hello, world!
"; 
    t.expires_from_now(boost::posix_time::seconds(1)); 
    t.async_wait(print); 
    std::cout << "Print executed
"; 
} 
int main() 
{ 
    t.async_wait(print); 
    boost::thread monitoring_thread = boost::thread(run_io_service); 
    boost::this_thread::sleep(boost::posix_time::seconds(2)); 
    t.cancel(); 
    std::cout << "Resetting Timer
"; 
    t.async_wait(print); 
    boost::this_thread::sleep(boost::posix_time::seconds(2)); 
    t.cancel(); 
    io.stop(); 
    monitoring_thread.join(); 
    return 0; 
} 

此代碼工作正常,直到時間計時器尚未取消。 一旦定時器被取消,定時器不能以預期的方式工作,它根本不起作用。

我在做什麼錯?

+0

你能否澄清你期望這個程序輸出什麼,它實際輸出什麼,以及爲什麼你認爲這意味着定時器不工作? – 2014-11-24 08:10:12

沙发
0
2

第一個問題是如果出現錯誤(例如被取消),處理程序仍將被調用,則需要檢查錯誤代碼。

void print(const boost::system::error_code& e) 
{ 
    if(e) return; // we were cancelled 
    // actual error code for cancelled is boost::asio::error::operation_aborted 

    boost::mutex::scoped_lock lock(mtx1); 
    std::cout << "Hello, world!
"; 
    t.expires_from_now(boost::posix_time::seconds(1)); 
    t.async_wait(print); 
    std::cout << "Print executed
"; 
} 

其次,當你取消計時器,離開了io_service對象沒有任何工作,這意味着run_io_service線程將終止,讓你沒有服務。整個節目過程中保持服務活着,給它一個工作對象在主開始:

int main() { 
    boost::asio::io_service::work work(io); 
    ... 

和..如sehe提到的,你是不是安全處理的定時器(或std ::法院) 。當你打印重置信息並重置定時器時,你應該鎖定mtx1,否則墨菲法則規定它可能在處理程序正在運行並且弄亂了事情的時刻發生。

+0

這是現貨。 +1 – sehe 2014-11-24 08:24:22

板凳
0
2

您需要設置新的過期時間。

事實上,您不必在此事件中明確取消,因爲設置新的期望會隱式取消任何待處理的異步等待。

請記住deadline_timer對象本身並不是線程安全的,因此您需要保持計時器突變同步。

+0

謝謝。處理錯誤幫助。 那麼,每次我們需要重置計時器時,我們不需要停止io服務嗎?在相同的定時器上使用async_wait會重置它? – garima721 2014-11-24 11:34:09

+0

不,是的。你可以隨時查看文檔。 (順便提一下,'io_service'是線程安全的) – sehe 2014-11-24 11:52:39

+0

非常感謝。這解決了我的問題。 – garima721 2014-11-25 02:48:03