Linux的C编程中多线程如何终止某个线程示例与要点

示例 demo
最简单的 demo:
static void* thread1_func(void *arg)
{
int i = 0;
// able to be cancel
pthread_setcancelstate(pthread_cancel_enable, null);
pthread_setcanceltype(pthread_cancel_deferred, null);
for(i=0; ; i++) {
printf(“thread1 %d
”, i);
sleep(1);
}
}
int main(int argc, char **argv)
{
pthread_t t;
void *res;
pthread_create(&t, null, thread1_func, null);
sleep(3);
pthread_cancel(t); // cancel thread1
pthread_join(t, &res); // wait thread1
if (res == pthread_canceled)
printf(“thread1 was terminate by cancel
”);
else
printf(“thread1 was not terminate by cancel
”);
exit(exit_success);
}
为了突出重点,省略了检查返回值。
运行效果:
thread1 0
thread1 1
thread1 2
thread1 was terminate by cancel
主线程先创建线程 thread1,然后睡眠 3 秒后发出终止 thread1 的请求。
接收到终止请求后,thread1 会在合适的时机被终止掉。
主线程通过 pthread_join() 阻塞等待 thread1 退出。
几个要点
线程终止的 4 种方式:
线程的执行函数返回了,这和 main() 函数结束类似。
线程调用了 pthread_exit() 函数,这和调用 exit() 返回类似。
线程被另一个线程通过 pthread_cancel() 函数取消,这和通过kill() 发送 sigkill 信号类似。
进程终止了,则进程中的所有线程也会终止。
取消某个线程的常规步骤
被取消的线程:
允许取消,pthread_setcancelstate(),参数可选值:
pthread_cancel_enable,这是默认值;
pthread_cancel_disable;
设置取消类型,pthread_setcanceltype(),参数可选值:
pthread_cancel_asynchronous,异步方式,当发出取消请求后,线程可能会在任何点被杀死。
pthread_cancel_deferred,延迟方式,线程只会在特定的取消点(cancellation points,调用某个函数前)被杀死。
发起取消的线程:
发送取消要求,pthread_cancel(),发出取消请求后,pthread_cancel() 当即返回,不会等待目标线程的退出。
等待取消完成,pthread_join()。
哪些函数是取消点?
posix.1 指定了哪些函数一定是取消点:
更多关于取消点的介绍:
$ man 7 pthreads
cancellation points
。..
accept()
aio_suspend()
clock_nanosleep()
close()
。..
阅读开源软件 mjpg-streamer
mjpg-streamer 是什么?
简单地说,就是一个开源的流媒体服务器:
https://github.com/jacksonliam/mjpg-streamer
通过 mjpg-streamer,你可以通过 pc 浏览器访问到板子上的摄像头图像。
mjpg-streamer 是如何结束工作线程的?
mjpg-streamer 运行时一般会有 3 个线程:
主线程;
负责数据的输入的线程 (例如 camera capture thread);
负责输出数据的线程 (例如 http server thread)。
以 http server thread 为例:
plugins/output_http/httpd.c
void *server_thread(void *arg)
{
。..
pthread_cleanup_push(server_cleanup, pcontext);
// 处理连接
while(!pglobal-》stop) {
。..
}
pthread_cleanup_pop(1);
}
pthread_cleanup_push() 用于注册清理函数到栈中,当线程遭取消时,会沿该栈自顶向下依次执行清理函数。
当用户通过按下 ctrl + c 要求结束程序时,主线程会要求杀掉 http server thread 等各种线程:
static void signal_handler(int sig)
{
for(i = 0; i 《 global.outcnt; i++) {
。..
pthread_cancel(servers[id].threadid);
。..
}
}
接下来,当 http server thread 遇到某个取消点时,server_cleanup() 会被调用以完成清理工作。
这里只是简单地分析一下,mjpg-streamer 里多线程相关的代码挺复杂的,有兴趣的小伙伴们自行阅读吧。


CNE将在国家能源网中采取区块链技术用于数据认证
基于改进FCOS的表面缺陷检测算法
芯在路上:ST MCU生态系统大解析
机器人界意识到:技术需要走出实验室,进入现实世界
“依托英飞凌IGBT和SiC技术的CIPOSIPM在工业领域的应用”网络研讨会上的问答
Linux的C编程中多线程如何终止某个线程示例与要点
中国电信天翼3G覆盖342座城市
低成本紧凑型荧光灯镇流器设计电路图
降压芯片AP2911完美替代LN2556恒流IC
威盛电子发布首款基于ARM架构的工业系统
机器人产业终端应用厂商参会名单
适用于物联网高级应用的高性能NORA-B1蓝牙模块
小米手环4nfc版体验 和2代手环没有什么本质的区别
电磁污染及其防治
肖特基二极管技术与结构
比利时半导体厂商成立弗兰德斯半导体协会
眨眼学会PWM
焦化“四大车”无线联锁方案
2019第五届中国人工智能大会在青岛胶州方圆体育中心开幕
爆料称Intel将推出特殊CPU Kaby Lake+AMD Radeon核显