Board logo

标题: 如何使用 C++11 编写 Linux 多线程程序(2)如何创建和结束一个线程 [打印本页]

作者: look_w    时间: 2018-4-22 13:39     标题: 如何使用 C++11 编写 Linux 多线程程序(2)如何创建和结束一个线程

如何创建和结束一个线程和 pthread_create 不同,使用 thread 类创建线程可以使用一个函数作为入口,也可以是其它的 Callable 对象,而且,可以给入口传入任意个数任意类型的参数:
清单 2.例子 thread_run_func_var_args.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
int funcReturnInt(const char* fmt, ...){
va_list ap;
va_start(ap, fmt);
vprintf( fmt, ap );
va_end(ap);
return 0xabcd;
}
void threadRunFunction(void){
thread* t = new thread(funcReturnInt, "%d%s\n", 100, "\%");
t->join();
delete t;
}
我们也可以传入一个 Lambda 表达式作为入口,比如:




清单 3.例子 thread_run_lambda.cc
1
2
3
4
5
6
7
8
9
10
11
void threadRunLambda(void){
int a = 100,
b = 200;
thread* t = new thread( [](int ia, int ib){
cout << (ia + ib) << endl;
},
a,
b );
t->join();
delete t;
}




一个类的成员函数也可以作为线程入口:
清单 4.例子 thread_run_member_func.cc
1
2
3
4
5
6
7
8
9
10
11
struct God{
void create(const char* anything){
cout << "create " << anything << endl;
}
};
void threadRunMemberFunction(void){
God god;
thread* t = new thread( &God::create, god, "the world" );
t->join();
delete t;
}




虽然 thread 类的初始化可以提供这么丰富和方便的形式,其实现的底层依然是创建一个 pthread 线程并运行之,有些实现甚至是直接调用 pthread_create 来创建。
创建一个线程之后,我们还需要考虑一个问题:该如何处理这个线程的结束?一种方式是等待这个线程结束,在一个合适的地方调用 thread 实例的 join() 方法,调用者线程将会一直等待着目标线程的结束,当目标线程结束之后调用者线程继续运行;另一个方式是将这个线程分离,由其自己结束,通过调用 thread 实例的 detach() 方法将目标线程置于分离模式。一个线程的 join() 方法与 detach() 方法只能调用一次,不能在调用了 join() 之后又调用 detach(),也不能在调用 detach() 之后又调用 join(),在调用了 join() 或者 detach() 之后,该线程的 id 即被置为默认值(空线程),表示不能继续再对该线程作修改变化。如果没有调用 join() 或者 detach(),那么,在析构的时候,该线程实例将会调用 std::terminate(),这会导致整个进程退出,所以,如果没有特别需要,一般都建议在生成子线程后调用其 join() 方法等待其退出,这样子最起码知道这些子线程在什么时候已经确保结束。
在 C++11 里面没有提供 kill 掉某个线程的能力,只能被动地等待某个线程的自然结束,如果我们要主动停止某个线程的话,可以通过调用 Linux 操作系统提供的 pthread_kill 函数给目标线程发送信号来实现,示例如下:
清单 5.例子 thread_kill.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
static void on_signal_term(int sig){
cout << "on SIGTERM:" << this_thread::get_id() << endl;
pthread_exit(NULL);
}
void threadPosixKill(void){
signal(SIGTERM, on_signal_term);
thread* t = new thread( [](){
while(true){
++counter;
}
});
pthread_t tid = t->native_handle();
cout << "tid=" << tid << endl;
// 确保子线程已经在运行。
this_thread::sleep_for( chrono::seconds(1) );
pthread_kill(tid, SIGTERM);
t->join();
delete t;
cout << "thread destroyed." << endl;
}






欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0