目錄
找出線程ID
銷毀指定執行緒
為什麼停止執行緒這麼難
如何溫柔退出線程
擴充功能
擴充
首頁 後端開發 Python教學 Python執行緒中定位與銷毀的詳細介紹(附範例)

Python執行緒中定位與銷毀的詳細介紹(附範例)

Feb 20, 2019 pm 02:41 PM
c linux python

這篇文章帶給大家的內容是關於Python線程中定位與銷毀的詳細介紹(附示例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

開工前我就覺得有什麼不太對勁,感覺要背鍋。這可不,上班第三天就捅鍋了。

我們有個了不起的後台程序,可以動態載入模組,並以執行緒方式運行,透過這種形式實現外掛程式的功能。而模組更新時候,後台程式本身不會退出,只會將模組對應的執行緒關閉、更新程式碼再啟動,6 得不行。

於是乎我就寫了個模組準備大展身手,結果忘記寫退出函數了,導致每次更新模組都新創建一個線程,除非重啟那個程序,否則那些線程就一直苟活著。

這可不行啊,得想個辦法清理呀,要不然怕是要炸了。

那麼怎麼清理呢?我能想到的就是兩步走:

  1. 找出需要清理的線程號tid;

  2. 銷毀它們;

找出線程ID

和平時的故障排查相似,先透過ps 指令看看目標行程的執行緒情況,因為已經是setName 設定過執行緒名,所以正常來說應該是看到對應的線程的。直接用下面程式​​碼來模擬這個執行緒:

Python 版本的多執行緒

#coding: utf8
import threading
import os
import time

def tt():
    info = threading.currentThread()
    while True:
        print 'pid: ', os.getpid()
        print info.name, info.ident
        time.sleep(3)

t1 = threading.Thread(target=tt)
t1.setName('OOOOOPPPPP')
t1.setDaemon(True)
t1.start()

t2 = threading.Thread(target=tt)
t2.setName('EEEEEEEEE')
t2.setDaemon(True)
t2.start()


t1.join()
t2.join()
登入後複製
登入後複製

#輸出:

root@10-46-33-56:~# python t.py
pid:  5613
OOOOOPPPPP 139693508122368
pid:  5613
EEEEEEEEE 139693497632512
...
登入後複製
登入後複製

可以看到在Python 裡面輸出的執行緒名稱就是我們設定的那樣,然而Ps 的結果卻是令我懷疑人生:

root@10-46-33-56:~# ps -Tp 5613
  PID  SPID TTY          TIME CMD
 5613  5613 pts/2    00:00:00 python
 5613  5614 pts/2    00:00:00 python
 5613  5615 pts/2    00:00:00 python
登入後複製
登入後複製

正常來說不該是這樣呀,我有點迷了,難道我一直都是記錯了?用別的語言版本的多執行緒來測試下:

C 版本的多執行緒

#include<stdio.h>
#include<sys>
#include<sys>
#include<pthread.h>

void *test(void *name)
{    
    pid_t pid, tid;
    pid = getpid();
    tid = syscall(__NR_gettid);
    char *tname = (char *)name;
    
    // 设置线程名字
    prctl(PR_SET_NAME, tname);
    
    while(1)
    {
        printf("pid: %d, thread_id: %u, t_name: %s\n", pid, tid, tname);
        sleep(3);
    }
}

int main()
{
    pthread_t t1, t2;
    void *ret;
    pthread_create(&t1, NULL, test,  (void *)"Love_test_1");
    pthread_create(&t2, NULL, test,  (void *)"Love_test_2");
    pthread_join(t1, &ret);
    pthread_join(t2, &ret);
}</pthread.h></sys></sys></stdio.h>
登入後複製
登入後複製

輸出:

root@10-46-33-56:~# gcc t.c -lpthread && ./a.out
pid: 5575, thread_id: 5577, t_name: Love_test_2
pid: 5575, thread_id: 5576, t_name: Love_test_1
pid: 5575, thread_id: 5577, t_name: Love_test_2
pid: 5575, thread_id: 5576, t_name: Love_test_1
...
登入後複製
登入後複製

用PS 指令再次驗證:

root@10-46-33-56:~# ps -Tp 5575
  PID  SPID TTY          TIME CMD
 5575  5575 pts/2    00:00:00 a.out
 5575  5576 pts/2    00:00:00 Love_test_1
 5575  5577 pts/2    00:00:00 Love_test_2
登入後複製
登入後複製

這個才是正確嘛,線程名確實是可以透過Ps 看出來的嘛!

不過為啥 Python 那個看不到呢?既然是透過setName 設定線程名的,那就看看定義咯:

[threading.py]
class Thread(_Verbose):
    ...
    @property
    def name(self):
        """A string used for identification purposes only.

        It has no semantics. Multiple threads may be given the same name. The
        initial name is set by the constructor.

        """
        assert self.__initialized, "Thread.__init__() not called"
        return self.__name

    @name.setter
    def name(self, name):
        assert self.__initialized, "Thread.__init__() not called"
        self.__name = str(name)
        
    def setName(self, name):
        self.name = name
    ...
登入後複製
登入後複製

看到這裡其實只是在Thread 物件的屬性設定了而已,並沒有動到根本,那肯定就是看不到咯~

這樣看起來,我們已經沒辦法透過ps/proc/ 這類手段在外部搜尋python 線程名了,所以我們只能在Python 內部來解決。

於是問題就變成了,怎麼能在 Python 內部拿到所有正在執行的執行緒呢?

threading.enumerate  可以完美解決這個問題! Why?

Because 在下面這個函數的 doc 裡面說得很清楚了,傳回所有活躍的執行緒物件,不包括終止和未啟動的。

[threading.py]

def enumerate():
    """Return a list of all Thread objects currently alive.

    The list includes daemonic threads, dummy thread objects created by
    current_thread(), and the main thread. It excludes terminated threads and
    threads that have not yet been started.

    """
    with _active_limbo_lock:
        return _active.values() + _limbo.values()
登入後複製
登入後複製

因為拿到的是 Thread 的對象,所以我們透過這個能到該線程相關的資訊!

請看完整程式碼範例:

#coding: utf8

import threading
import os
import time


def get_thread():
    pid = os.getpid()
    while True:
        ts = threading.enumerate()
        print '------- Running threads On Pid: %d -------' % pid
        for t in ts:
            print t.name, t.ident
        print
        time.sleep(1)
        
def tt():
    info = threading.currentThread()
    pid = os.getpid()
    while True:
        print 'pid: {}, tid: {}, tname: {}'.format(pid, info.name, info.ident)
        time.sleep(3)
        return

t1 = threading.Thread(target=tt)
t1.setName('Thread-test1')
t1.setDaemon(True)
t1.start()

t2 = threading.Thread(target=tt)
t2.setName('Thread-test2')
t2.setDaemon(True)
t2.start()

t3 = threading.Thread(target=get_thread)
t3.setName('Checker')
t3.setDaemon(True)
t3.start()

t1.join()
t2.join()
t3.join()
登入後複製
登入後複製

輸出:

root@10-46-33-56:~# python t_show.py
pid: 6258, tid: Thread-test1, tname: 139907597162240
pid: 6258, tid: Thread-test2, tname: 139907586672384

------- Running threads On Pid: 6258 -------
MainThread 139907616806656
Thread-test1 139907597162240
Checker 139907576182528
Thread-test2 139907586672384

------- Running threads On Pid: 6258 -------
MainThread 139907616806656
Thread-test1 139907597162240
Checker 139907576182528
Thread-test2 139907586672384

------- Running threads On Pid: 6258 -------
MainThread 139907616806656
Thread-test1 139907597162240
Checker 139907576182528
Thread-test2 139907586672384

------- Running threads On Pid: 6258 -------
MainThread 139907616806656
Checker 139907576182528
...
登入後複製
登入後複製

程式碼看起來有點長,但是邏輯相當簡單,Thread-test1Thread-test2 都是印出目前的pid、執行緒id 和執行緒名字,然後3s 後退出,這個是想模擬執行緒正常退出。

Checker 執行緒則是每秒透過 threading.enumerate 輸出目前行程內所有活躍的執行緒。

可以明顯看到一開始是可以看到Thread-test1Thread-test2的訊息,當它兩個退出之後就只剩下 MainThreadChecker 本身而已了。

銷毀指定執行緒

既然能拿到名字和執行緒 id,那我們也就能幹掉指定的執行緒了!

假設現在Thread-test2 已經黑化,發瘋了,我們需要阻止它,那我們就可以透過這種方式解決了:

在上面的程式碼基礎上,增加和補上下列程式碼:

def _async_raise(tid, exctype):
    """raises the exception, performs cleanup if needed"""
    tid = ctypes.c_long(tid)
    if not inspect.isclass(exctype):
        exctype = type(exctype)
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
    if res == 0:
        raise ValueError("invalid thread id")
    elif res != 1:
        ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
        raise SystemError("PyThreadState_SetAsyncExc failed")

def stop_thread(thread):
    _async_raise(thread.ident, SystemExit)

def get_thread():
    pid = os.getpid()
    while True:
        ts = threading.enumerate()
        print '------- Running threads On Pid: %d -------' % pid
        for t in ts:
            print t.name, t.ident, t.is_alive()
            if t.name == 'Thread-test2':
                print 'I am go dying! Please take care of yourself and drink more hot water!'
                stop_thread(t)
        print
        time.sleep(1)
登入後複製
登入後複製

輸出

root@10-46-33-56:~# python t_show.py
pid: 6362, tid: 139901682108160, tname: Thread-test1
pid: 6362, tid: 139901671618304, tname: Thread-test2
------- Running threads On Pid: 6362 -------
MainThread 139901706389248 True
Thread-test1 139901682108160 True
Checker 139901661128448 True
Thread-test2 139901671618304 True
Thread-test2: I am go dying. Please take care of yourself and drink more hot water!

------- Running threads On Pid: 6362 -------
MainThread 139901706389248 True
Thread-test1 139901682108160 True
Checker 139901661128448 True
Thread-test2 139901671618304 True
Thread-test2: I am go dying. Please take care of yourself and drink more hot water!

pid: 6362, tid: 139901682108160, tname: Thread-test1
------- Running threads On Pid: 6362 -------
MainThread 139901706389248 True
Thread-test1 139901682108160 True
Checker 139901661128448 True
// Thread-test2 已经不在了
登入後複製
登入後複製

一餐操作下來,雖然我們這樣對待Thread-test2,但它還是關心著我們:多喝熱水

PS: 熱水雖好,八杯足矣,請勿貪杯哦。

書回正傳,上述的方法是極為粗暴的,為什麼這麼說呢?

因為它的原理是:利用Python 內建的API,觸發指定執行緒的異常,讓其可以自動退出;

Python執行緒中定位與銷毀的詳細介紹(附範例)

萬不得已真不要用這種方法,有一定機率觸發不可描述的問題。切記!別問我為什麼會知道...

為什麼停止執行緒這麼難

多執行緒本身設計就是在進程下的協作並發,是調度的最小單元,執行緒間分食著進程的資源,所以會有許多鎖定機制和狀態控制。

如果使用強製手段幹掉線程,那麼很大幾率就會出現意想不到的bug。 而且最重要的鎖定資源釋放可能也會出現意想不到問題。

我們甚至無法透過訊號殺死進程那樣直接殺線程,因為 kill 只有對付程序才能達到我們的預期,而對付線程明顯不可以,不管殺哪個線程,整個行程都會退出!

而因為有 GIL,使得許多童鞋都覺得 Python 的線程是Python 自行實現出來的,並非實際存在,Python 應該可以直接銷毀吧?

然而事實上 Python 的線程都是貨真價實的線程!

什麼意思呢? Python 的執行緒是作業系統透過 pthread 建立的原生執行緒。 Python  只是透過 GIL 來約束這些線程,來決定什麼時候開始調度,比方說運行了多少個指令就交出 GIL,至於誰奪得花魁,得聽操作系統的。

如果是單純的線程,其實係統是有辦法終止的,例如: pthread_exit,pthread_kill  或pthread_cancel,  詳情可看: https://www.cnblogs.com/Creat...

可惜的是: Python 層面並沒有這些方法的封裝!我的天,好氣!可能人家覺得,線程就該溫柔對待吧。

如何溫柔退出線程

想要溫柔退出線程,其實差不多就是一句廢話了~

要么運行完退出,要么設置標誌位,時常檢查標記位,該退出的就退出咯。

擴充功能

《如何正確的終止正在運行的子執行緒》:https://www.cnblogs.com/Creat...
《不要粗暴的銷毀python執行緒》 :http://xiaorui.cc/2017/02/22/...

#歡迎各位大神指點交流, QQ討論群: 258498217
轉載請註明來源: https://segmentfault.com/a/11...







######################                                            上##############################################################

##                                                                                                                                               

  •                                                                   
  • #

    Python:執行緒之定位與銷毀
  • Python執行緒中定位與銷毀的詳細介紹(附範例)

  • #c

##linux

############################linux######################## ##########                                                                                 python############             266 次閱讀                                                 ·                                                 時所學。                                                                                        #################



                           8#                        

##                        

#                        #                        

#                        #                        #                    

背景

##開工前我覺得有什麼不太對勁,感覺要背鍋。這可不,上班第三天就捅鍋了。

我們有個了不起的後台程序,可以動態載入模組,並以執行緒方式運行,透過這種形式實現外掛程式的功能。而模組更新時候,後台程式本身不會退出,只會將模組對應的執行緒關閉、更新程式碼再啟動,6 得不行。

於是乎我就寫了個模組準備大展身手,結果忘記寫退出函數了,導致每次更新模組都新創建一個線程,除非重啟那個程序,否則那些線程就一直苟活著。

這可不行啊,得想個辦法清理呀,要不然怕是要炸了。

那麼怎麼清理呢?我能想到的就是兩步走:

找出需要清理的線程號tid;

銷毀它們;

找出線程ID

和平時的故障排查相似,先透過ps 指令看看目標行程的執行緒情況,因為已經是setName 設定過執行緒名,所以正常來說應該是看到對應的線程的。直接用下面程式​​碼來模擬這個執行緒:

Python 版本的多執行緒

#coding: utf8
import threading
import os
import time

def tt():
    info = threading.currentThread()
    while True:
        print 'pid: ', os.getpid()
        print info.name, info.ident
        time.sleep(3)

t1 = threading.Thread(target=tt)
t1.setName('OOOOOPPPPP')
t1.setDaemon(True)
t1.start()

t2 = threading.Thread(target=tt)
t2.setName('EEEEEEEEE')
t2.setDaemon(True)
t2.start()


t1.join()
t2.join()
登入後複製
登入後複製
#輸出:
root@10-46-33-56:~# python t.py
pid:  5613
OOOOOPPPPP 139693508122368
pid:  5613
EEEEEEEEE 139693497632512
...
登入後複製
登入後複製
可以看到在Python 裡面輸出的執行緒名稱就是我們設定的那樣,然而Ps 的結果卻是令我懷疑人生:
root@10-46-33-56:~# ps -Tp 5613
  PID  SPID TTY          TIME CMD
 5613  5613 pts/2    00:00:00 python
 5613  5614 pts/2    00:00:00 python
 5613  5615 pts/2    00:00:00 python
登入後複製
登入後複製
正常來說不該是這樣呀,我有點迷了,難道我一直都是記錯了?用別的語言版本的多執行緒來測試下:C 版本的多執行緒

#include<stdio.h>
#include<sys>
#include<sys>
#include<pthread.h>

void *test(void *name)
{    
    pid_t pid, tid;
    pid = getpid();
    tid = syscall(__NR_gettid);
    char *tname = (char *)name;
    
    // 设置线程名字
    prctl(PR_SET_NAME, tname);
    
    while(1)
    {
        printf("pid: %d, thread_id: %u, t_name: %s\n", pid, tid, tname);
        sleep(3);
    }
}

int main()
{
    pthread_t t1, t2;
    void *ret;
    pthread_create(&t1, NULL, test,  (void *)"Love_test_1");
    pthread_create(&t2, NULL, test,  (void *)"Love_test_2");
    pthread_join(t1, &ret);
    pthread_join(t2, &ret);
}</pthread.h></sys></sys></stdio.h>
登入後複製
登入後複製

輸出:

root@10-46-33-56:~# gcc t.c -lpthread && ./a.out
pid: 5575, thread_id: 5577, t_name: Love_test_2
pid: 5575, thread_id: 5576, t_name: Love_test_1
pid: 5575, thread_id: 5577, t_name: Love_test_2
pid: 5575, thread_id: 5576, t_name: Love_test_1
...
登入後複製
登入後複製
用PS 指令再次驗證:

root@10-46-33-56:~# ps -Tp 5575
  PID  SPID TTY          TIME CMD
 5575  5575 pts/2    00:00:00 a.out
 5575  5576 pts/2    00:00:00 Love_test_1
 5575  5577 pts/2    00:00:00 Love_test_2
登入後複製
登入後複製
這個才是正確嘛,線程名確實是可以透過Ps 看出來的嘛! 不過為啥 Python 那個看不到呢?既然是透過

setName

設定線程名的,那就看看定義咯:

[threading.py]
class Thread(_Verbose):
    ...
    @property
    def name(self):
        """A string used for identification purposes only.

        It has no semantics. Multiple threads may be given the same name. The
        initial name is set by the constructor.

        """
        assert self.__initialized, "Thread.__init__() not called"
        return self.__name

    @name.setter
    def name(self, name):
        assert self.__initialized, "Thread.__init__() not called"
        self.__name = str(name)
        
    def setName(self, name):
        self.name = name
    ...
登入後複製
登入後複製
看到這裡其實只是在

Thread 物件的屬性設定了而已,並沒有動到根本,那肯定就是看不到咯~這樣看起來,我們已經沒辦法透過ps

/proc/

這類手段在外部搜尋python 線程名了,所以我們只能在Python 內部來解決。 ######於是問題就變成了,怎麼能在 Python 內部拿到所有正在執行的執行緒呢? #########threading.enumerate###  可以完美解決這個問題! Why?######Because 在下面這個函數的 doc 裡面說得很清楚了,傳回所有活躍的###執行緒物件###,不包括終止和未啟動的。 ###
[threading.py]

def enumerate():
    """Return a list of all Thread objects currently alive.

    The list includes daemonic threads, dummy thread objects created by
    current_thread(), and the main thread. It excludes terminated threads and
    threads that have not yet been started.

    """
    with _active_limbo_lock:
        return _active.values() + _limbo.values()
登入後複製
登入後複製
###因為拿到的是 Thread 的對象,所以我們透過這個能到該線程相關的資訊! ######請看完整程式碼範例:###
#coding: utf8

import threading
import os
import time


def get_thread():
    pid = os.getpid()
    while True:
        ts = threading.enumerate()
        print '------- Running threads On Pid: %d -------' % pid
        for t in ts:
            print t.name, t.ident
        print
        time.sleep(1)
        
def tt():
    info = threading.currentThread()
    pid = os.getpid()
    while True:
        print 'pid: {}, tid: {}, tname: {}'.format(pid, info.name, info.ident)
        time.sleep(3)
        return

t1 = threading.Thread(target=tt)
t1.setName('Thread-test1')
t1.setDaemon(True)
t1.start()

t2 = threading.Thread(target=tt)
t2.setName('Thread-test2')
t2.setDaemon(True)
t2.start()

t3 = threading.Thread(target=get_thread)
t3.setName('Checker')
t3.setDaemon(True)
t3.start()

t1.join()
t2.join()
t3.join()
登入後複製
登入後複製
###輸出:###
root@10-46-33-56:~# python t_show.py
pid: 6258, tid: Thread-test1, tname: 139907597162240
pid: 6258, tid: Thread-test2, tname: 139907586672384

------- Running threads On Pid: 6258 -------
MainThread 139907616806656
Thread-test1 139907597162240
Checker 139907576182528
Thread-test2 139907586672384

------- Running threads On Pid: 6258 -------
MainThread 139907616806656
Thread-test1 139907597162240
Checker 139907576182528
Thread-test2 139907586672384

------- Running threads On Pid: 6258 -------
MainThread 139907616806656
Thread-test1 139907597162240
Checker 139907576182528
Thread-test2 139907586672384

------- Running threads On Pid: 6258 -------
MainThread 139907616806656
Checker 139907576182528
...
登入後複製
登入後複製
###程式碼看起來有點長,但是邏輯相當簡單,###Thread-test1### 和# ##Thread-test2### 都是印出目前的pid、執行緒id 和執行緒名字,然後3s 後退出,這個是想模擬執行緒正常退出。 ######而 ###Checker### 執行緒則是每秒透過 ###threading.enumerate### 輸出目前行程內所有活躍的執行緒。 ######可以明顯看到一開始是可以看到###Thread-test1### 和###Thread-test2###的訊息,當它兩個退出之後就只剩下### MainThread### 和###Checker### 本身而已了。 ######銷毀指定執行緒######既然能拿到名字和執行緒 id,那我們也就能幹掉指定的執行緒了! ######假設現在###Thread-test2### 已經黑化,發瘋了,我們需要阻止它,那我們就可以透過這種方式解決了:######在上面的程式碼基礎上,增加和補上下列程式碼:###
def _async_raise(tid, exctype):
    """raises the exception, performs cleanup if needed"""
    tid = ctypes.c_long(tid)
    if not inspect.isclass(exctype):
        exctype = type(exctype)
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
    if res == 0:
        raise ValueError("invalid thread id")
    elif res != 1:
        ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
        raise SystemError("PyThreadState_SetAsyncExc failed")

def stop_thread(thread):
    _async_raise(thread.ident, SystemExit)

def get_thread():
    pid = os.getpid()
    while True:
        ts = threading.enumerate()
        print '------- Running threads On Pid: %d -------' % pid
        for t in ts:
            print t.name, t.ident, t.is_alive()
            if t.name == 'Thread-test2':
                print 'I am go dying! Please take care of yourself and drink more hot water!'
                stop_thread(t)
        print
        time.sleep(1)
登入後複製
登入後複製
###輸出###
root@10-46-33-56:~# python t_show.py
pid: 6362, tid: 139901682108160, tname: Thread-test1
pid: 6362, tid: 139901671618304, tname: Thread-test2
------- Running threads On Pid: 6362 -------
MainThread 139901706389248 True
Thread-test1 139901682108160 True
Checker 139901661128448 True
Thread-test2 139901671618304 True
Thread-test2: I am go dying. Please take care of yourself and drink more hot water!

------- Running threads On Pid: 6362 -------
MainThread 139901706389248 True
Thread-test1 139901682108160 True
Checker 139901661128448 True
Thread-test2 139901671618304 True
Thread-test2: I am go dying. Please take care of yourself and drink more hot water!

pid: 6362, tid: 139901682108160, tname: Thread-test1
------- Running threads On Pid: 6362 -------
MainThread 139901706389248 True
Thread-test1 139901682108160 True
Checker 139901661128448 True
// Thread-test2 已经不在了
登入後複製
登入後複製
###一餐操作下來,雖然我們這樣對待###Thread-test2###,但它還是關心著我們:###多喝熱水###,######PS: 熱水雖好,八杯足矣,請勿貪杯哦。 ###

書回正傳,上述的方法是極為粗暴的,為什麼這麼說呢?

因為它的原理是:利用Python 內建的API,觸發指定執行緒的異常,讓其可以自動退出;

Python執行緒中定位與銷毀的詳細介紹(附範例)

萬不得已真不要用這種方法,有一定機率觸發不可描述的問題。切記!別問我為什麼會知道...

為什麼停止執行緒這麼難

多執行緒本身設計就是在進程下的協作並發,是調度的最小單元,執行緒間分食著進程的資源,所以會有許多鎖定機制和狀態控制。

如果使用強製手段幹掉線程,那麼很大幾率就會出現意想不到的bug。 而且最重要的鎖定資源釋放可能也會出現意想不到問題。

我們甚至無法透過訊號殺死進程那樣直接殺線程,因為 kill 只有對付程序才能達到我們的預期,而對付線程明顯不可以,不管殺哪個線程,整個進程都會退出!

而因為有 GIL,使得許多童鞋都覺得 Python 的線程是Python 自行實現出來的,並非實際存在,Python 應該可以直接銷毀吧?

然而事實上 Python 的線程都是貨真價實的線程!

什麼意思呢? Python 的執行緒是作業系統透過 pthread 建立的原生執行緒。 Python  只是透過 GIL 來約束這些線程,來決定什麼時候開始調度,比方說運行了多少個指令就交出 GIL,至於誰奪得花魁,得聽操作系統的。

如果是單純的線程,其實係統是有辦法終止的,例如: pthread_exit,pthread_kill  或pthread_cancel,  詳情可看: https://www.cnblogs.com/Creat...

可惜的是: Python 層面並沒有這些方法的封裝!我的天,好氣!可能人家覺得,線程就該溫柔對待吧。

如何溫柔退出線程

想要溫柔退出線程,其實差不多就是一句廢話了~

要么運行完退出,要么設置標誌位,時常檢查標記位,該退出的就退出咯。

擴充

《如何正確的終止正在運行的子執行緒》:https://www.cnblogs.com/Creat...
《不要粗暴的銷毀python執行緒》 :http://xiaorui.cc/2017/02/22/...

#歡迎各位大神指點交流, QQ討論群: 258498217
轉載請註明來源: https://segmentfault.com/a/11...

  • #保留所有權利


回報






如果你覺得我的文章對你有用,請隨意讚賞


你可能感興趣的



2 評論

                                                                       時間排序


           

##############################################################################################################################                                            ######################水平))                    ######                    ####  ‧  1 天前###                ################若是我可能kill -9了,寧可錯殺一千,不可放過一個,蛤蛤###

                       #                                                #                    #                     回覆                                    


#                                #                                    #                                        0                                             #                                #                                                        



##啊~ -9 流程裡一樣全死了~

##########啊~#########>

                                                                                                                                                                                                                  #                                    #                                         —                                                                                    上Python執行緒中定位與銷毀的詳細介紹(附範例)##1                                                                                

                                                

                                       

 ‧  1 天前中上

                                               

新增回覆

載入中...

#顯示更多評論

##### #######

以上是Python執行緒中定位與銷毀的詳細介紹(附範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1665
14
CakePHP 教程
1424
52
Laravel 教程
1322
25
PHP教程
1270
29
C# 教程
1249
24
PHP和Python:解釋了不同的範例 PHP和Python:解釋了不同的範例 Apr 18, 2025 am 12:26 AM

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

在PHP和Python之間進行選擇:指南 在PHP和Python之間進行選擇:指南 Apr 18, 2025 am 12:24 AM

PHP適合網頁開發和快速原型開發,Python適用於數據科學和機器學習。 1.PHP用於動態網頁開發,語法簡單,適合快速開發。 2.Python語法簡潔,適用於多領域,庫生態系統強大。

Linux體系結構:揭示5個基本組件 Linux體系結構:揭示5個基本組件 Apr 20, 2025 am 12:04 AM

Linux系統的五個基本組件是:1.內核,2.系統庫,3.系統實用程序,4.圖形用戶界面,5.應用程序。內核管理硬件資源,系統庫提供預編譯函數,系統實用程序用於系統管理,GUI提供可視化交互,應用程序利用這些組件實現功能。

PHP和Python:深入了解他們的歷史 PHP和Python:深入了解他們的歷史 Apr 18, 2025 am 12:25 AM

PHP起源於1994年,由RasmusLerdorf開發,最初用於跟踪網站訪問者,逐漸演變為服務器端腳本語言,廣泛應用於網頁開發。 Python由GuidovanRossum於1980年代末開發,1991年首次發布,強調代碼可讀性和簡潔性,適用於科學計算、數據分析等領域。

Golang vs. Python:性能和可伸縮性 Golang vs. Python:性能和可伸縮性 Apr 19, 2025 am 12:18 AM

Golang在性能和可擴展性方面優於Python。 1)Golang的編譯型特性和高效並發模型使其在高並發場景下表現出色。 2)Python作為解釋型語言,執行速度較慢,但通過工具如Cython可優化性能。

Python與C:學習曲線和易用性 Python與C:學習曲線和易用性 Apr 19, 2025 am 12:20 AM

Python更易學且易用,C 則更強大但複雜。 1.Python語法簡潔,適合初學者,動態類型和自動內存管理使其易用,但可能導致運行時錯誤。 2.C 提供低級控制和高級特性,適合高性能應用,但學習門檻高,需手動管理內存和類型安全。

laravel安裝代碼 laravel安裝代碼 Apr 18, 2025 pm 12:30 PM

要安裝 Laravel,需依序進行以下步驟:安裝 Composer(適用於 macOS/Linux 和 Windows)安裝 Laravel 安裝器創建新項目啟動服務訪問應用程序(網址:http://127.0.0.1:8000)設置數據庫連接(如果需要)

Python vs.C:探索性能和效率 Python vs.C:探索性能和效率 Apr 18, 2025 am 12:20 AM

Python在開發效率上優於C ,但C 在執行性能上更高。 1.Python的簡潔語法和豐富庫提高開發效率。 2.C 的編譯型特性和硬件控制提升執行性能。選擇時需根據項目需求權衡開發速度與執行效率。

See all articles