示例 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 里多線程相關的代碼挺復雜的,有興趣的小伙伴們自行閱讀吧。
編輯:lyn
-
Linux
+關注
關注
87文章
11319瀏覽量
209830 -
多線程
+關注
關注
0文章
278瀏覽量
20016 -
c編程
+關注
關注
0文章
94瀏覽量
29366
原文標題:Linux-C編程 / 多線程 / 如何終止某個線程?
文章出處:【微信號:zhuyandz,微信公眾號:FPGA之家】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論