C++中std::thread线程用法
1:std::thread的基本用法
最简单的 std::thread用法如下,调用 thread将立即同时开始执行这个新建立的线程,新线程的任务执行完毕之后, main()的主线程也会继续执行。
#include<iostream> #include<thread> #include<windows.h> #include<string> using namespace std; void myfunc_work() { cout << "myfunc_work ....." << endl; // do something 5s Sleep(5000); } int main() { std::thread t1(myfunc_work); // 阻塞当前main主线程,待子线程执行完毕后,自己恢复主线程逻辑 t1.join(); cout << "main thread ....." << endl; }
2:std:: thread常用的成员函数
下面为C++ std::thread常用的成员函数
get_id() 取得目前的线程 id, 回传一个 std::thread::id 类型
joinable() 检查是否可 join
join() // 阻塞当前线程,等待子线程执行完毕
detach() // 与该线程分离,一旦该线程执行完后它所分配的资源就会被释放
native_handle() 取得平台原生的 native handle.
sleep_for() // 停止目前线程一段指定的时间
yield() // 暂时放弃CPU一段时间,让给其他线程
void foo() { cout << "foo\n"; } void bar(int x) { cout << "bar\n"; } int main() { //std::thread t1(myfunc_work); //cout << "main thread ....." << endl; 阻塞当前main主线程,待子线程执行完毕后,自己恢复主线程逻辑 //t1.join(); thread t1(foo); thread t2(bar, 10); cout << "main,foo,bar execute concurrently....\n"; cout << "sleep 1s\n"; this_thread::sleep_for(chrono::seconds(2)); cout << "join t1\n"; t1.join(); cout << "join t2\n"; t2.join(); cout << "foo and bar thread complete"; }
很显然:新线程建立后,是否立即执行新线程业务代码,有一定的随机性。
但是我们可以通过 thread.join() 或者 sleep_for() 来控制代码执行顺序
3:建立新 thread执行类别中的函数
C++ std::thread 的构建可以传入class类别中的成员函数,如下范例所示:AA::start 分别建立t1, t2 两个线程,而 t1传入 AA::a1 类别函数。
notice :
第一个参数:AA::a1 前面需要添加 &
第二个参数:代表的是那个类对象
后面参数: 按照要求传入即可
class AA { public: void a1() { cout << "a1\n"; } void a2(int n) { cout << "a2 : " << n << "\n"; } void start() { thread t1(&AA::a1, this); thread t2(&AA::a2, this,10); t1.join(); t2.join(); } private: };
4:建立新 thread 执行 lambda expression
std:: thread 的构建也可以传入 lambda expression 表达式,如下范例:
5:join等待thread执行结束
在main主线程建立 t1线程后,主线程便继续往下执行,如果主线程需要等待 t1执行完毕后才能继续执行的话,就需要使用 join 。
等待 t1线程执行完 foo 后主线程才能继续执行,如果 t1线程没有执行完,主线程会一致阻塞在 join这一行。
void test2() { cout << "foo begin...." << endl; this_thread::sleep_for(chrono::milliseconds(5000)); cout << "foo end...." << endl; } int main() { std::thread t1(test2); cout << "main 1....." << endl;; t1.join(); cout << "main 2....."; cout << "main thread run over" << endl; }
6:detach不等待 thread执行结束
承上例:如果主线程不想等或者可以不用等待 t1线程,可以使用 detach来让 t1线程分离,接着主线程就可以继续执行,t1线程 也在继续执行。
/** join等待thread执行结束 */ void test2() { cout << "foo begin...." << endl; this_thread::sleep_for(chrono::milliseconds(50)); cout << "foo end...." << endl; } int main() { std::thread t1(test2); cout << "main 1....." << endl;; t1.detach(); cout << "main 2....."<< endl; cout << "main thread run over" << endl; Sleep(2000); return 0; }
7:std::thread 参数传递使用引用的方法
定义方法:
void myFunc(int& n) { std::cout << "myFunc n = " << n << endl; n+= 10; }
使用参数传递使用引用目的是: 希望建立另外一个线程去执行 myFunc , 之后需要取得这个 myFunc的运算结果,但是建立线程如果写: std::thread t1(myFunc , n) 这样会编译出错。
因为在 std::thread 的参数传递方式为值传递,值传递是不可修改的左值,如果要让其能修改,可以考虑通过 : std::ref 来达成。
void myFunc(int n) { std::cout << "myFunc n = " << n << endl; n += 10; } void myFunc_ref(int& n) { std::cout << "myFunc reference n = " << n << endl; n += 10; } int main() { int n1 = 5; thread t1(myFunc, n1); t1.join(); cout << "main n1 = " << n1 << "\n"; int n2 = 10; thread t2(myFunc_ref, std::ref(n2)); t2.join(); cout << "main n2 = " << n2 << "\n"; cout << "main thread run over" << endl; return 0; }
到此这篇关于C++中std::thread线程用法的文章就介绍到这了,更多相关C++ std::thread线程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
C++11中初始化列表initializer lists的使用方法
C++11引入了初始化列表来初始化变量和对象,自定义类型,如果想用初始化列表就要包含initializer_list头文件2021-09-09
最新评论