C ++线程的简单例子
有人可以发布一个简单的例子,在C ++中启动两个(面向对象)线程。
我正在寻找实际的C ++线程对象,我可以扩展运行方法(或类似的东西),而不是调用一个C风格的线程库。
更新 – 我遗漏了任何操作系统特定的请求,希望谁回复谁会回答跨平台库使用。 我只是现在就明确表示。
创build一个你想让线程执行的函数。 我将用一个简单的例子来演示:
void task1(std::string msg) { std::cout << "task1 says: " << msg; }
现在创build将最终调用上面的函数的thread
对象,如下所示:
std::thread t1(task1, "Hello");
(你需要#include <thread>
来访问std::thread
类)
正如你所看到的,构造函数的参数是线程将执行的函数,后面是函数的参数。
最后,将它join到你的主执行线程中,如下所示:
t1.join();
(join意味着调用新线程的线程将等待新线程完成执行,然后继续自己的执行)。
代码
#include <string> #include <iostream> #include <thread> using namespace std; // The function we want to execute on the new thread. void task1(string msg) { cout << "task1 says: " << msg; } int main() { // Constructs the new thread and runs it. Does not block execution. thread t1(task1, "Hello"); // Makes the main thread wait for the new thread to finish execution, therefore blocks its own execution. t1.join(); }
更多关于std :: thread的信息在这里
- 在GCC上,用
-std=c++0x -pthread
编译。 - 这应该适用于任何操作系统,只要你的编译器支持这个(C ++ 11)特性。
那么,从技术上来说,任何这样的对象都将被封装在一个C风格的线程库上,因为C ++只是在c ++ 0x中指定了一个股票std::thread
模型,而这个模型刚刚被钉住了,还没有被实现。 这个问题有点系统性,从技术上说,现有的c ++内存模型不够严格,无法为所有'发生之前'的情况提供明确的语义。 汉斯·鲍姆(Hans Boehm)早就写了一篇关于这个话题的文章,并且在这个话题上发挥了c ++ 0x标准的作用。
http://www.hpl.hp.com/techreports/2004/HPL-2004-209.html
这就是说有几个跨平台的线程C ++库在实践中工作得很好。 英特尔线程构build块包含一个非常接近c ++ 0x标准的tbb :: thread对象,而Boost有一个boost ::线程库。
http://www.threadingbuildingblocks.org/
http://www.boost.org/doc/libs/1_37_0/doc/html/thread.html
使用boost :: thread你会得到像这样的东西:
#include <boost/thread.hpp> void task1() { // do stuff } void task2() { // do stuff } int main (int argc, char ** argv) { using namespace boost; thread thread_1 = thread(task1); thread thread_2 = thread(task2); // do other stuff thread_2.join(); thread_1.join(); return 0; }
还有一个用于POSIX操作系统的POSIX库。 检查兼容性
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <iostream> void *task(void *argument){ char* msg; msg = (char*)argument; std::cout<<msg<<std::endl; } int main(){ pthread_t thread1, thread2; int i1,i2; i1 = pthread_create( &thread1, NULL, task, (void*) "thread 1"); i2 = pthread_create( &thread1, NULL, task, (void*) "thread 2"); pthread_join(thread1,NULL); pthread_join(thread2,NULL); return 0; }
用-lpthread编译
这在很大程度上取决于你决定使用的图书馆。 例如,如果你使用wxWidgets库,创build一个线程将如下所示:
class RThread : public wxThread { public: RThread() : wxThread(wxTHREAD_JOINABLE){ } private: RThread(const RThread ©); public: void *Entry(void){ //Do... return 0; } }; wxThread *CreateThread() { //Create thread wxThread *_hThread = new RThread(); //Start thread _hThread->Create(); _hThread->Run(); return _hThread; }
如果你的主线程调用CreateThread方法,你将创build一个新的线程开始在你的“Entry”方法中执行代码。 在大多数情况下,你必须保持对线程的引用来join或停止它。 更多信息在这里: wxThread文档
这是创build任意数量的线程(在C ++ 11或更新版本中)的更健壮的方法:
#include <thread> #include <iostream> using namespace std; void doSomething(int id) { cout << "Thread id = " << id; } /** * Spawns n threads */ void spawnThreads(int n) { thread threads[n]; // spawn n threads: for (int i = 0; i < n; i++) { threads[i] = thread(doSomething, i + 1); } for (auto& th : threads) { th.join(); } }
当search一个在新线程中调用自己的实例方法的C ++类的例子时,这个问题就出现了,但是我们无法以这种方式使用任何这些答案。 下面是一个例子:
Class.h
class DataManager { public: bool hasData; void getData(); bool dataAvailable(); };
Class.cpp
#include "DataManager.h" void DataManager::getData() { // perform background data munging hasData = true; // be sure to notify on the main thread } bool DataManager::dataAvailable() { if (hasData) { return true; } else { std::thread t(&DataManager::getData, this); t.detach(); // as opposed to .join, which runs on the current thread } }
请注意,这个例子不会进入互斥锁或locking状态。
除非在全局namespacs中需要单独的函数,否则我们可以使用lambda函数来创build线程。
使用lambda创build线程的主要优点之一是我们不需要将本地参数作为参数列表传递。 我们可以使用相同的捕获列表,lambda的闭包属性将负责生命周期。
这是一个示例代码
int main() { int localVariable = 100; thread th { [=](){ cout<<"The Value of local variable => "<<localVariable<<endl; }} th.join(); return 0; }
到目前为止,我发现C ++ lambdaexpression式是创build线程的最佳方式,尤其是对于更简单的线程函数