示例 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ī)被終止掉。
主線程通過 pthread_join() 阻塞等待 thread1 退出。
幾個(gè)要點(diǎn)
線程終止的 4 種方式:
線程的執(zhí)行函數(shù)返回了,這和 main() 函數(shù)結(jié)束類似。
線程調(diào)用了 pthread_exit() 函數(shù),這和調(diào)用 exit() 返回類似。
線程被另一個(gè)線程通過 pthread_cancel() 函數(shù)取消,這和通過kill() 發(fā)送 SIGKILL 信號(hào)類似。
進(jìn)程終止了,則進(jìn)程中的所有線程也會(huì)終止。
取消某個(gè)線程的常規(guī)步驟
被取消的線程:
允許取消,pthread_setcancelstate(),參數(shù)可選值:
PTHREAD_CANCEL_ENABLE,這是默認(rèn)值;
PTHREAD_CANCEL_DISABLE;
設(shè)置取消類型,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()
。..
閱讀開源軟件 MJPG-streamer
MJPG-streamer 是什么?
簡(jiǎn)單地說,就是一個(gè)開源的流媒體服務(wù)器:
https://github.com/jacksonliam/mjpg-streamer
通過 mjpg-streamer,你可以通過 PC 瀏覽器訪問到板子上的攝像頭圖像。
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)用戶通過按下 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);
。..
}
}
接下來,當(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文章
11312瀏覽量
209713 -
多線程
+關(guān)注
關(guān)注
0文章
278瀏覽量
20001 -
c編程
+關(guān)注
關(guān)注
0文章
94瀏覽量
29363
原文標(biāo)題:Linux-C編程 / 多線程 / 如何終止某個(gè)線程?
文章出處:【微信號(hào):zhuyandz,微信公眾號(hào):FPGA之家】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論