线程正常退出的几种方式:
在线程工作函数中调用pthread_exit,此时可使用pthread_join接收pthread_exit的参数值
线程工作函数运行结束
同一进程中的任意一个子线程调用exit,或者主线程结束
线程可以被从另一个线程中取消pthread_cancel
void pthread_exit(void *retval);
retval指示的返回值,可用pthread_join进行接收源码
#include
#include
#include
#include
void *start_routine(void *ptr)
{
printf("子线程(%lu)开始运行...\n", pthread_self());
int num = 0;
while (1)
{
printf("子线程(%lu)正在执行,%d...\n", pthread_self(), ++num);
sleep(1);
if (num > 3)
pthread_exit((void **)"8888");
}
printf("子线程(%lu)即将退出...\n", pthread_self());
return (void *)"9999";
}
int main(int argc, char const *argv[])
{
printf("主线程(%lu)开始运行...\n", pthread_self());
pthread_t thread_id;
pthread_create(&thread_id, NULL, start_routine, NULL);
void *retval = NULL;
pthread_join(thread_id, &retval);
printf("子线程的返回值为:%s\n", (const char *)retval);
printf("主线程(%lu)即将退出...\n", pthread_self());
exit(EXIT_SUCCESS);
}
输出
主线程(140657300412224)开始运行…
子线程(140657300408064)开始运行…
子线程(140657300408064)正在执行,1…
子线程(140657300408064)正在执行,2…
子线程(140657300408064)正在执行,3…
子线程(140657300408064)正在执行,4…
子线程的返回值为:8888
主线程(140657300412224)即将退出…
int pthread_cancel(pthread_t thread);
发送一个取消请求。目标线程是否响应与什么时候响应依赖于可取消状态与可取消类型属性。
int pthread_setcancelstate(int state, int *oldstate);
可取消状态可通过函数pthread_setcancelstate函数进行设置。默认为启用。
PTHREAD_CANCEL_DISABLE)了可取消状态属性,则取消请求将保留到可取消状态被启用PTHREAD_CANCEL_ENABLE)了可取消状态属性,则可取消类型决定取消行为什么时候发生int pthread_setcanceltype(int type, int *oldtype);
可以取消类型可通过函数pthread_setcanceltype函数进行设置。可能值为异步与延迟。
异步(PTHREAD_CANCEL_ASYNCHRONOUS)
异步的可取消类型意味着可以在任意时刻取消(通常是立即取消,但系统不保证)。
延迟(PTHREAD_CANCEL_DEFERRED)
异步的可取消类型意味着取消被延迟直到下次调用取消点函数
取消点函数列表可通过
man 7 pthreads进行查询
void pthread_cleanup_push(void (*routine)(void *), void *arg);
void pthread_cleanup_pop(int execute);
当一个取消请求被实施,将按下述步骤进行实施:
pthread_cleanup_push)源码
#include
#include
#include
#include
void *start_routine_01(void *ptr)
{
printf("子线程(%lu)开始运行...\n", pthread_self());
int num = 0;
while (1)
{
printf("子线程(%lu)正在执行,%d...\n", pthread_self(), ++num);
sleep(1);
}
printf("子线程(%lu)即将退出...\n", pthread_self());
return (void *)"8888";
}
void *start_routine_02(void *ptr)
{
printf("子线程(%lu)开始运行...\n", pthread_self());
sleep(3);
pthread_cancel(*((pthread_t*)ptr));
printf("子线程(%lu)取消信号已发出\n", pthread_self());
printf("子线程(%lu)即将退出...\n", pthread_self());
return (void *)"9999";
}
int main(int argc, char const *argv[])
{
printf("主线程(%lu)开始运行...\n", pthread_self());
pthread_t thread_id_01;
pthread_create(&thread_id_01, NULL, start_routine_01, NULL);
pthread_t thread_id_02;
pthread_create(&thread_id_02, NULL, start_routine_02, &thread_id_01);
pthread_join(thread_id_01, NULL);
pthread_join(thread_id_02, NULL);
printf("主线程(%lu)即将退出...\n", pthread_self());
exit(EXIT_SUCCESS);
}
输出
主线程(140162664855360)开始运行…
子线程(140162664851200)开始运行…
子线程(140162664851200)正在执行,1…
子线程(140162656458496)开始运行…
子线程(140162664851200)正在执行,2…
子线程(140162664851200)正在执行,3…
子线程(140162664851200)正在执行,4…
子线程(140162656458496)取消信号已发出
子线程(140162656458496)即将退出…
主线程(140162664855360)即将退出…