Linux-C编程 / 多线程 / 如何终止某个线程?
示例 demo
最簡(jiǎn)單的 demo:
static?void*?thread1_func(void?*arg) {int?i?=?0;//?able?to?be?cancelpthread_setcancelstate(PTHREAD_CANCEL_ENABLE,?NULL);pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,?NULL);for(i=0;?;?i++)?{printf("thread1?%d\n",?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?thread1pthread_join(t,?&res);??????//?wait?thread1if?(res?==?PTHREAD_CANCELED)printf("thread1?was?terminate?by?cancel\n");elseprintf("thread1?was?not?terminate?by?cancel\n");exit(EXIT_SUCCESS); }為了突出重點(diǎn),省略了檢查返回值。
運(yùn)行效果:
thread1?0 thread1?1 thread1?2 thread1?was?terminate?by?cancel主線程先創(chuàng)建線程 thread1,然后睡眠 3 秒后發(fā)出終止 thread1 的請(qǐng)求。
接收到終止請(qǐng)求后,thread1 會(huì)在合適的時(shí)機(jī)被終止掉。
主線程通過(guò) pthread_join() 阻塞等待 thread1 退出。
幾個(gè)要點(diǎn)
線程終止的 4 種方式:
線程的執(zhí)行函數(shù)返回了,這和 main() 函數(shù)結(jié)束類(lèi)似。
線程調(diào)用了 pthread_exit() 函數(shù),這和調(diào)用 exit() 返回類(lèi)似。
線程被另一個(gè)線程通過(guò) pthread_cancel() 函數(shù)取消,這和通過(guò)kill() 發(fā)送 SIGKILL 信號(hào)類(lèi)似。
進(jìn)程終止了,則進(jìn)程中的所有線程也會(huì)終止。
取消某個(gè)線程的常規(guī)步驟
被取消的線程:
允許取消,pthread_setcancelstate(),參數(shù)可選值:
PTHREAD_CANCEL_ENABLE,這是默認(rèn)值;
PTHREAD_CANCEL_DISABLE;
設(shè)置取消類(lèi)型,pthread_setcanceltype(),參數(shù)可選值:
PTHREAD_CANCEL_ASYNCHRONOUS,異步方式,當(dāng)發(fā)出取消請(qǐng)求后,線程可能會(huì)在任何點(diǎn)被殺死。
PTHREAD_CANCEL_DEFERRED,延遲方式,線程只會(huì)在特定的取消點(diǎn)(cancellation points,調(diào)用某個(gè)函數(shù)前)被殺死。
發(fā)起取消的線程:
發(fā)送取消要求,pthread_cancel(),發(fā)出取消請(qǐng)求后,pthread_cancel() 當(dāng)即返回,不會(huì)等待目標(biāo)線程的退出。
等待取消完成,pthread_join()。
主線程;
負(fù)責(zé)數(shù)據(jù)的輸入的線程 (例如 camera capture thread);
負(fù)責(zé)輸出數(shù)據(jù)的線程 (例如 http server thread).
開(kāi)源軟件 / MJPG-Streamer
Linux 系統(tǒng)編程(第2版) / 7.7.6 終止線程
Linux 程序設(shè)計(jì)(第4版) / 12.7 取消一個(gè)線程
Linux-Unix 系統(tǒng)編程手冊(cè) / 32 線程:線程取消
Unix 環(huán)境高級(jí)編程 / 11.5 線程終止
哪些函數(shù)是取消點(diǎn)?
POSIX.1 指定了哪些函數(shù)一定是取消點(diǎn):
點(diǎn)擊查看大圖更多關(guān)于取消點(diǎn)的介紹:
$?man?7?pthreadsCancellation?points...accept()aio_suspend()clock_nanosleep()close()...閱讀開(kāi)源軟件 MJPG-streamer
MJPG-streamer 是什么?
簡(jiǎn)單地說(shuō),就是一個(gè)開(kāi)源的流媒體服務(wù)器:
https://github.com/jacksonliam/mjpg-streamer
通過(guò) mjpg-streamer,你可以通過(guò) PC 瀏覽器訪問(wèn)到板子上的攝像頭圖像。
MJPG-streamer 是如何結(jié)束工作線程的?
MJPG-streamer 運(yùn)行時(shí)一般會(huì)有 3 個(gè)線程:
以 http server thread 為例:
plugins/output_http/httpd.cvoid?*server_thread(void?*arg) {...pthread_cleanup_push(server_cleanup,?pcontext);//?處理連接while(!pglobal->stop)?{...}pthread_cleanup_pop(1); }pthread_cleanup_push() 用于注冊(cè)清理函數(shù)到棧中,當(dāng)線程遭取消時(shí),會(huì)沿該棧自頂向下依次執(zhí)行清理函數(shù)。
當(dāng)用戶通過(guò)按下 ctrl + c 要求結(jié)束程序時(shí),主線程會(huì)要求殺掉 http server thread 等各種線程:
static?void?signal_handler(int?sig) {for(i?=?0;?i?<?global.outcnt;?i++)?{...pthread_cancel(servers[id].threadID);...} }接下來(lái),當(dāng) http server thread 遇到某個(gè)取消點(diǎn)時(shí),server_cleanup() 會(huì)被調(diào)用以完成清理工作。
這里只是簡(jiǎn)單地分析一下,MJPG-Streamer 里多線程相關(guān)的代碼挺復(fù)雜的,有興趣的小伙伴們自行閱讀吧。
相關(guān)參考
思考技術(shù),也思考人生
要學(xué)習(xí)技術(shù),更要學(xué)習(xí)如何生活。
你和我各有一個(gè)蘋(píng)果,如果我們交換蘋(píng)果的話,我們還是只有一個(gè)蘋(píng)果。但當(dāng)你和我各有一個(gè)想法,我們交換想法的話,我們就都有兩個(gè)想法了。
推薦閱讀:
專(zhuān)輯|Linux文章匯總
專(zhuān)輯|程序人生
專(zhuān)輯|C語(yǔ)言
我的知識(shí)小密圈
總結(jié)
以上是生活随笔為你收集整理的Linux-C编程 / 多线程 / 如何终止某个线程?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 数据库变为可疑_Sql 2008数据库可
- 下一篇: 工作笔记——海康威视网络摄像头接入华为云