示例 demo
最簡(jiǎn)單的 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);
}
為了突出重點(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()。
哪些函數(shù)是取消點(diǎn)?
POSIX.1 指定了哪些函數(shù)一定是取消點(diǎn):
更多關(guān)于取消點(diǎn)的介紹:
$ man 7 pthreads
Cancellation 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è)線程:
主線程;
負(fù)責(zé)數(shù)據(jù)的輸入的線程 (例如 camera capture thread);
負(fù)責(zé)輸出數(shù)據(jù)的線程 (例如 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() 用于注冊(cè)清理函數(shù)到棧中,當(dāng)線程遭取消時(shí),會(huì)沿該棧自頂向下依次執(zhí)行清理函數(shù)。
當(dāng)用戶(hù)通過(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ù)雜的,有興趣的小伙伴們自行閱讀吧。
編輯:lyn
-
Linux
+關(guān)注
關(guān)注
87文章
11406瀏覽量
212080 -
多線程
+關(guān)注
關(guān)注
0文章
279瀏覽量
20198 -
c編程
+關(guān)注
關(guān)注
0文章
94瀏覽量
29499
原文標(biāo)題:Linux-C編程 / 多線程 / 如何終止某個(gè)線程?
文章出處:【微信號(hào):zhuyandz,微信公眾號(hào):FPGA之家】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
進(jìn)程、線程、協(xié)程傻傻分不清?一文帶你徹底扒光它們的\"底褲\"!
請(qǐng)問(wèn)如何在Python中實(shí)現(xiàn)多線程與多進(jìn)程的協(xié)作?
請(qǐng)問(wèn)rt-thread studio如何進(jìn)行多線程編譯?
socket 多線程編程實(shí)現(xiàn)方法
Python中多線程和多進(jìn)程的區(qū)別

CPU線程和程序線程的區(qū)別
從多線程設(shè)計(jì)模式到對(duì) CompletableFuture 的應(yīng)用

探索虛擬線程:原理與實(shí)現(xiàn)

鴻蒙開(kāi)發(fā):【線程模型】

動(dòng)態(tài)線程池思想學(xué)習(xí)及實(shí)踐

評(píng)論