最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++多線程強(qiáng)制終止詳細(xì)

 更新時(shí)間:2021年09月26日 11:31:22   作者:我是一顆大西瓜  
這篇文章主要介紹了C++多線程強(qiáng)制終止, 實(shí)際上,沒有任何語言或操作系統(tǒng)可以為你提供異步突然終止線程的便利,且不會(huì)警告你不要使用它們。但是下面我們?cè)賮砗?jiǎn)單看看相關(guān)內(nèi)容吧

前言:

故事的起因來源于我在優(yōu)化他人c++源碼的時(shí)候,想通過多線程的方式提升程序的運(yùn)算效率,主要存在以下需求和難點(diǎn):

  • 多個(gè)線程并行跑模型,看哪個(gè)模型跑的快,跑出來后結(jié)束其他線程,線程間獨(dú)立運(yùn)行無通信過程
  • 源碼模型很復(fù)雜,函數(shù)調(diào)用較多,不好改動(dòng),因此不太適合通過信號(hào)或標(biāo)志進(jìn)行通信終止

線程結(jié)束的幾種方式:

線程函數(shù)的return返回(建議):這種退出線程的方式是最安全的,在線程函數(shù)return返回后, 會(huì)清理函數(shù)內(nèi)申請(qǐng)的類對(duì)象, 即調(diào)用這些對(duì)象的析構(gòu)函數(shù).。然后會(huì)自動(dòng)調(diào)用 _endthreadex()函數(shù)來清理 _beginthreadex()函數(shù)申請(qǐng)的資源(主要是創(chuàng)建的tiddata對(duì)象)。
同一個(gè)進(jìn)程或另一個(gè)進(jìn)程中的線程調(diào)用TerminateThread函數(shù)(應(yīng)避免使用該方法):TerminateThread能夠撤消任何線程,其中hThread參數(shù)用于標(biāo)識(shí)被終止運(yùn)行的線程的句柄。當(dāng)線程終止運(yùn)行時(shí),它的退出代碼成為你作為dwExitCode參數(shù)傳遞的值。同時(shí),線程的內(nèi)核對(duì)象的使用計(jì)數(shù)也被遞減。注意TerminateThread函數(shù)是異步運(yùn)行的函數(shù),也就是說,它告訴系統(tǒng)你想要線程終止運(yùn)行,但是,當(dāng)函數(shù)返回時(shí),不能保證線程被撤消。如果需要確切地知道該線程已經(jīng)終止運(yùn)行,必須調(diào)用WaitForSingleObject或者類似的函數(shù),傳遞線程的句柄。
通過調(diào)用ExitThread函數(shù):線程將自行撤消(最好不使用該方法)。該函數(shù)將終止線程的運(yùn)行,并導(dǎo)致操作系統(tǒng)清除該線程使用的所有操作系統(tǒng)資源。但是,C++資源(如C++類對(duì)象)將不被析構(gòu)。
ExitProcess和TerminateProcess函數(shù)也可以用來終止線程的運(yùn)行(應(yīng)避免使用該方法):
選項(xiàng)2和3可能會(huì)導(dǎo)致內(nèi)存泄漏,實(shí)際上,沒有任何語言或操作系統(tǒng)可以為你提供異步突然終止線程的便利,且不會(huì)警告你不要使用它們。所有這些執(zhí)行環(huán)境都強(qiáng)烈建議開發(fā)人員,甚至要求在協(xié)作或同步線程終止的基礎(chǔ)上構(gòu)建多線程應(yīng)用程序。

現(xiàn)有的線程結(jié)束函數(shù),包括linux系統(tǒng)的pthread.h中的pthread_exit()pthread_cancel(),windows系統(tǒng)的win32.h中的ExitThread()TerminateThread(),也就是說,C++沒有提供kill掉某個(gè)線程的能力,只能被動(dòng)地等待某個(gè)線程的自然結(jié)束,析構(gòu)函數(shù)~thread()也不能停止線程,析構(gòu)函數(shù)只能在線程靜止時(shí)終止線程joinable,對(duì)于連接/分離的線程,析構(gòu)函數(shù)根本無法終止線程。

要終止與OS /編譯器相關(guān)的函數(shù)的線程,我們需要知道如何從C++獲取本機(jī)線程數(shù)據(jù)類型std::thread。幸運(yùn)的是,在調(diào)用或之前std::thread提供了一個(gè)API native_handle()以獲取線程的本機(jī)句柄類型。并且可以將此本地句柄傳遞給本地OS線程終止函數(shù),例如join() detach() pthread_cancel()。

以下代碼用于顯示std::thread::native_handle()std::thread::get_id()pthread_self()返回相同的代碼pthread_t來處理Linux / GCC的C++線程

#include <mutex>
#include <iostream>
#include <chrono>
#include <cstring>
#include <pthread.h>
 
std::mutex iomutex;
void f(int num)
{
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::lock_guard<std::mutex> lk(iomutex);
    std::cout << "Thread " << num << " pthread_t " << pthread_self() << std::endl;
}
 
int main()
{
    std::thread t1(f, 1), t2(f, 2);
    
    //t1.join(); t2.join();  ----------------pos 1
    //t1.detach(); t2.detach(); -------------pos 2
    
    std::cout << "Thread 1 thread id " << t1.get_id() << std::endl;
    std::cout << "Thread 2 thread id " << t2.get_id() << std::endl;
    
    std::cout << "Thread 1 native handle " << t1.native_handle() << std::endl;
    std::cout << "Thread 2 native handle " << t2.native_handle() << std::endl;
    
    t1.join(); t2.join();
    //t1.detach(); t2.detach();
}

運(yùn)行后可以得到結(jié)果

$ g++ -Wall -std=c++11 cpp_thread_pthread.cc -o cpp_thread_pthread -pthread -lpthread
$ ./cpp_thread_pthread
Thread 1 thread id 140109390030592
Thread 2 thread id 140109381637888
Thread 1 native handle 140109390030592
Thread 2 native handle 140109381637888
Thread 1 pthread_t 140109390030592
Thread 2 pthread_t 140109381637888

uncommentpos 1或者pos 2后,即調(diào)用join()或之后detach(),C++線程會(huì)丟失本機(jī)句柄類型的信息

$ ./cpp_thread_pthread
Thread 1 pthread_t 139811504355072
Thread 2 pthread_t 139811495962368
Thread 1 thread id thread::id of a non-executing thread
Thread 2 thread id thread::id of a non-executing thread
Thread 1 native handle 0
Thread 2 native handle 0

因此,要有效地調(diào)用本機(jī)線程終止函數(shù)(例如pthread_cancel),需要在調(diào)用std::thread::join()時(shí)或之前保存本機(jī)句柄std::thread::detach()。這樣,始終可以使用有效的本機(jī)句柄終止線程。

class Foo {
public:
    void sleep_for(const std::string &tname, int num)
    {
        prctl(PR_SET_NAME,tname.c_str(),0,0,0);        
        sleep(num);
    }

    void start_thread(const std::string &tname)
    {
        std::thread thrd = std::thread(&Foo::sleep_for, this, tname, 3600);
        tm_[tname] = thrd.native_handle();
        thrd.detach();
        std::cout << "Thread " << tname << " created:" << std::endl;
    }

    void stop_thread(const std::string &tname)
    {
        ThreadMap::const_iterator it = tm_.find(tname);
        if (it != tm_.end()) {
            pthread_cancel(it->second);
            tm_.erase(tname);
            std::cout << "Thread " << tname << " killed:" << std::endl;
        }
    }

private:
    typedef std::unordered_map<std::string, pthread_t> ThreadMap;
    ThreadMap tm_;
};

int main()
{
    Foo foo;
    std::string keyword("test_thread");
    std::string tname1 = keyword + "1";
    std::string tname2 = keyword + "2";

    // create and kill thread 1
    foo.start_thread(tname1);
    foo.stop_thread(tname1);

    // create and kill thread 2
    foo.start_thread(tname2);
    foo.stop_thread(tname2);

    return 0;
}

結(jié)果是:

$ g++ -Wall -std=c++11 kill_cpp_thread.cc -o kill_cpp_thread -pthread -lpthread
$ ./kill_cpp_thread
Thread test_thread1 created:
30332 30333 pts/5    00:00:00 test_thread1
Thread test_thread1 killed:
Thread test_thread2 created:
30332 30340 pts/5    00:00:00 test_thread2
Thread test_thread2 killed:

當(dāng)然,條件允許的話最好還是使用返回或信號(hào)的方式終止線程,這樣也符合安全可信的要求。

到此這篇關(guān)于C++多線程強(qiáng)制終止詳細(xì)的文章就介紹到這了,更多相關(guān)C++多線程強(qiáng)制終止內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • c語言動(dòng)態(tài)內(nèi)存分配知識(shí)點(diǎn)及實(shí)例

    c語言動(dòng)態(tài)內(nèi)存分配知識(shí)點(diǎn)及實(shí)例

    在本篇文章里小編給大家整理的是關(guān)于c語言動(dòng)態(tài)內(nèi)存分配知識(shí)點(diǎn)及實(shí)例,需要的朋友們可以學(xué)習(xí)下。
    2020-03-03
  • c++結(jié)合opencv如何實(shí)現(xiàn)讀取多張圖片并顯示

    c++結(jié)合opencv如何實(shí)現(xiàn)讀取多張圖片并顯示

    這篇文章主要介紹了c++結(jié)合opencv如何實(shí)現(xiàn)讀取多張圖片并顯示問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • c語言 漢諾塔算法代碼

    c語言 漢諾塔算法代碼

    c語言 漢諾塔算法代碼,需要的朋友可以參考一下
    2013-04-04
  • QT生成隨機(jī)驗(yàn)證碼的方法

    QT生成隨機(jī)驗(yàn)證碼的方法

    這篇文章主要為大家詳細(xì)介紹了QT生成隨機(jī)驗(yàn)證碼的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • C語言實(shí)現(xiàn)與電腦玩剪刀石頭布游戲

    C語言實(shí)現(xiàn)與電腦玩剪刀石頭布游戲

    這篇文章主要為大家詳細(xì)介紹了如何通過C語言實(shí)現(xiàn)和電腦玩剪刀石頭布游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-11-11
  • c文件匯編后函數(shù)參數(shù)傳遞的不同之處

    c文件匯編后函數(shù)參數(shù)傳遞的不同之處

    在w7 32位系統(tǒng)下把c文件匯編后,確實(shí)與mac后的差異很大??刹粌H僅是寄存器eax與rax的區(qū)別。我想說的是函數(shù)參數(shù)傳遞的不同
    2013-11-11
  • GCC 編譯c程序的方法及過程解析

    GCC 編譯c程序的方法及過程解析

    目前 Linux 下最常用的 C 語言編譯器是 GCC ( GNU Compiler Collection ),它是 GNU 項(xiàng)目中符合 ANSI C 標(biāo)準(zhǔn)的編譯系統(tǒng),能夠編譯用 C 、 C++ 和 Object C 等語言編寫的程序
    2014-01-01
  • C++實(shí)現(xiàn)將輸入復(fù)制到輸出的方法

    C++實(shí)現(xiàn)將輸入復(fù)制到輸出的方法

    這篇文章主要介紹了C++實(shí)現(xiàn)將輸入復(fù)制到輸出的方法,實(shí)例分析了C++字符串轉(zhuǎn)換及輸入輸出操作的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • c++編譯使用log4cplus的詳細(xì)步驟

    c++編譯使用log4cplus的詳細(xì)步驟

    C++很強(qiáng)大,但是仍然有很多不盡如人意的地方,比如打印日志方面就沒有java的log4j那種信手拈來,自然而然地東西,今天我們說一說一個(gè)很強(qiáng)大地日志庫log4cplus在c++項(xiàng)目中地使用,感興趣的朋友一起看看吧
    2023-10-10
  • 一起來學(xué)習(xí)C++中remove與erase的理解

    一起來學(xué)習(xí)C++中remove與erase的理解

    這篇文章主要為大家詳細(xì)介紹了C++的remove與erase,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03

最新評(píng)論

青河县| 克什克腾旗| 武功县| 宜都市| 镇安县| 芦溪县| 自贡市| 千阳县| 贵阳市| 图木舒克市| 吉木萨尔县| 南充市| 大姚县| 丹江口市| 大庆市| 太谷县| 安康市| 鄂托克旗| 桃园市| 金湖县| 昆明市| 惠东县| 宜黄县| 霍邱县| 弥渡县| 宜章县| 大田县| 包头市| 峡江县| 日照市| 抚顺市| 株洲县| 雅安市| 兰坪| 江油市| 三亚市| 新泰市| 河北省| 新乡县| 班戈县| 开阳县|