0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux的C編程中多線程如何終止某個(gè)線程示例與要點(diǎn)

FPGA之家 ? 來源:CSDN技術(shù)社區(qū) ? 作者:老吳的嵌入式之旅 ? 2021-04-27 13:41 ? 次閱讀

示例 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):

6db9b9f8-a67e-11eb-aece-12bb97331649.png

更多關(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

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 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)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    socket 多線程編程實(shí)現(xiàn)方法

    在現(xiàn)代網(wǎng)絡(luò)編程多線程技術(shù)被廣泛應(yīng)用于提高服務(wù)器的并發(fā)處理能力。Socket編程是網(wǎng)絡(luò)通信的基礎(chǔ),而將多線程技術(shù)應(yīng)用于Socket
    的頭像 發(fā)表于 11-12 14:16 ?380次閱讀

    Python多線程和多進(jìn)程的區(qū)別

    Python作為一種高級(jí)編程語言,提供了多種并發(fā)編程的方式,其中多線程與多進(jìn)程是最常見的兩種方式之一。在本文中,我們將探討Python多線程
    的頭像 發(fā)表于 10-23 11:48 ?411次閱讀
    Python<b class='flag-5'>中</b><b class='flag-5'>多線程</b>和多進(jìn)程的區(qū)別

    一文掌握Python多線程

    使用線程可以把占據(jù)長(zhǎng)時(shí)間的程序的任務(wù)放到后臺(tái)去處理。
    的頭像 發(fā)表于 08-05 15:46 ?871次閱讀

    ESP32會(huì)不會(huì)有多線程問題,需要加鎖嗎?

    ESP32會(huì)不會(huì)有多線程問題,需要加鎖嗎
    發(fā)表于 07-19 08:05

    多線程設(shè)計(jì)模式到對(duì) CompletableFuture 的應(yīng)用

    最近在開發(fā) 延保服務(wù) 頻道頁時(shí),為了提高查詢效率,使用到了多線程技術(shù)。為了對(duì)多線程方案設(shè)計(jì)有更加充分的了解,在業(yè)余時(shí)間讀完了《圖解 Java 多線程設(shè)計(jì)模式》這本書,覺得收獲良多。本篇文章將介紹其中
    的頭像 發(fā)表于 06-26 14:18 ?369次閱讀
    從<b class='flag-5'>多線程</b>設(shè)計(jì)模式到對(duì) CompletableFuture 的應(yīng)用

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

    管理其他線程的ArkTS引擎實(shí)例,例如使用TaskPool(任務(wù)池)創(chuàng)建任務(wù)或取消任務(wù)、啟動(dòng)和終止Worker線程。
    的頭像 發(fā)表于 06-13 16:38 ?425次閱讀
    鴻蒙開發(fā):【<b class='flag-5'>線程</b>模型】

    bootloader開多線程做引導(dǎo)程序,跳app初始化后直接進(jìn)hardfualt,為什么?

    如標(biāo)題,想做一個(gè)遠(yuǎn)程升級(jí)的項(xiàng)目,bootloader引導(dǎo)區(qū)域和app都是開多線程跑的,就是自己寫了個(gè)小的任務(wù)調(diào)度器,沒什么功能主要是想讓程序快速的響應(yīng),延時(shí)不會(huì)對(duì)其他程序造成堵塞,程序測(cè)試
    發(fā)表于 04-18 06:07

    鴻蒙原生應(yīng)用開發(fā)-ArkTS語言基礎(chǔ)類庫多線程I/O密集型任務(wù)開發(fā)

    使用異步并發(fā)可以解決單次I/O任務(wù)阻塞的問題,但是如果遇到I/O密集型任務(wù),同樣會(huì)阻塞線程其它任務(wù)的執(zhí)行,這時(shí)需要使用多線程并發(fā)能力來進(jìn)行解決。 I/O密集型任務(wù)的性能重點(diǎn)通常不在于CPU的處理
    發(fā)表于 03-21 14:57

    java實(shí)現(xiàn)多線程的幾種方式

    Java實(shí)現(xiàn)多線程的幾種方式 多線程是指程序包含了兩個(gè)或以上的線程,每個(gè)線程都可以并行執(zhí)行不同的任務(wù)或操作。Java
    的頭像 發(fā)表于 03-14 16:55 ?721次閱讀

    python5種線程鎖盤點(diǎn)

    線程安全是多線程或多進(jìn)程編程的一個(gè)概念,在擁有共享數(shù)據(jù)的多條線程并行執(zhí)行的程序
    發(fā)表于 03-07 11:08 ?1602次閱讀
    python<b class='flag-5'>中</b>5種<b class='flag-5'>線程</b>鎖盤點(diǎn)

    AT socket可以多線程調(diào)用嗎?

    請(qǐng)問AT socket 可以多線程調(diào)用嗎? 有互鎖機(jī)制嗎,還是要自己做互鎖。
    發(fā)表于 03-01 08:22

    什么是多核多線程?多核多線程如何提高程序的運(yùn)行效率?

    線程無法充分利用多核處理器的并行計(jì)算能力。
    的頭像 發(fā)表于 02-20 10:22 ?1384次閱讀

    linux多線程編程實(shí)例

    linux線程
    的頭像 發(fā)表于 02-15 21:16 ?478次閱讀
    <b class='flag-5'>linux</b><b class='flag-5'>多線程</b><b class='flag-5'>編程</b>實(shí)例

    Redis7單線程多線程詳解

    主要是指Redis的網(wǎng)絡(luò)IO和鍵值對(duì)讀寫是由一個(gè)線程來完成的。
    的頭像 發(fā)表于 01-16 17:33 ?1865次閱讀
    Redis7單<b class='flag-5'>線程</b>與<b class='flag-5'>多線程</b>詳解

    什么是守護(hù)線程?守護(hù)線程的底層原理和使用示例

    大家好,今天這篇文章來梳理一下有關(guān)守護(hù)線程的相關(guān)問題,這也是之前曾經(jīng)有被問到過的面試題,在此之前我們先看一看守護(hù)線程的使用示例。
    的頭像 發(fā)表于 01-05 11:01 ?1443次閱讀
    什么是守護(hù)<b class='flag-5'>線程</b>?守護(hù)<b class='flag-5'>線程</b>的底層原理和使用<b class='flag-5'>示例</b>