Python スレッドでの配置と破棄の詳細な紹介 (例付き)

不言
リリース: 2019-02-20 14:41:52
転載
2418 人が閲覧しました

この記事では、Python スレッドでの配置と破棄について詳しく説明します (例とともに)。一定の参考価値があります。困っている友人は参照できます。お役に立てれば幸いです。

仕事が始まる前に何かがおかしいと感じ、自分が責任を負わされるような気がしました。いや、罪悪感を感じるのは勤務3日目です。

モジュールを動的にロードしてスレッドで実行できる素晴らしいバックグラウンド プログラムがあり、これによりプラグインの機能を実現できます。モジュールが更新されると、バックグラウンド プログラム自体は終了せず、モジュールに対応するスレッドを閉じ、コードを更新してから開始するだけです。6 は不可能です。

そこで、自分のスキルを披露するためにモジュールを作成しましたが、exit 関数を書き忘れたため、モジュールが更新されるたびに新しいスレッドが作成されてしまいました。プログラムを再起動しない限り、それらのスレッドは生き続けてください。

これは不可能です。掃除する方法を見つけなければなりません。そうしないと爆発してしまうのではないかと心配です。

それでは、どうやって掃除すればいいのでしょうか?私が思いつくのは 2 つのステップだけです:

  1. クリーンアップする必要があるスレッド番号を見つけます;

  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 はこの問題を完全に解決できます。なぜですか?

次の関数のドキュメントに明確に記載されているため、終了したものと開始されていないものを除く、すべてのアクティブな スレッド オブジェクト が返されます。

[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、およびスレッド名を出力し、3 秒後に終了します。これは、スレッドの通常の終了をシミュレートするためです。

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)
ログイン後にコピー
ログイン後にコピー

Output

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 をこのように扱いますが、それでも引き続き考慮されます :もっと熱いお湯を飲みましょう,

追伸: 熱いお湯も良いですが、8杯で十分なので、欲張らないでください。

本題に戻りますが、上記の方法は非常に大雑把ですが、なぜそう言えるのでしょうか?

その原理は、Python の組み込み API を使用して指定されたスレッドで例外をトリガーし、スレッドが自動的に終了できるようにするためです。 # #この方法は最後の手段として使用しないでください。一定の確率で、言いようのない問題が発生する可能性があります。覚えて!なぜ知っているのかは聞かないでください...

スレッドを停止するのはなぜそれほど難しいのですかPython スレッドでの配置と破棄の詳細な紹介 (例付き)マルチスレッド自体は、プロセス下で協調的に同時実行できるように設計されています。スケジューリングとスレッドがプロセス リソースを共有するため、多くのロック メカニズムと状態制御が存在します。

強制的にスレッドを強制終了すると、予期せぬバグが発生する可能性が高くなります。また、最も重要なロック リソースの解放によって、予期しない問題が発生する可能性もあります。

kill はプロセスを処理することによってのみ期待を達成できるため、シグナルを通じてプロセスを強制終了するのと同じように、スレッドを直接強制終了することもできませんが、スレッドを処理することは明らかに不可能です。殺されると、プロセス全体が終了します。

そして、GIL のせいで、多くの子供たちは、Python のスレッドは Python 自体によって実装されており、実際には存在しないと考えています。Python は直接破棄されるべきですよね?

しかし、実際には、Python のスレッドは本物のスレッドです。 ######それはどういう意味ですか? Python スレッドは、pthread を通じてオペレーティング システムによって作成されるネイティブ スレッドです。 Python は、GIL を使用してこれらのスレッドを制約し、いつスケジュールを開始するかを決定するだけです。たとえば、多数の命令を実行した後、GIL を引き渡します。花魁が誰に勝つかについては、オペレーティング システムによって異なります。

これが単純なスレッドの場合、システムには実際には、

pthread_exit

pthread_killpthread_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...







c

linux
  • # Python

  • # 266 読書                                                             読むのに30分かかります                                                                                                                          



    # 8

                                                                                                                                                                                                                                                                                                                                                                                      背景仕事を始める前に何かがおかしいと感じ、自分が責任を負わされるような気がしました。いや、罪悪感を感じるのは勤務3日目です。

    そこで、自分のスキルを披露するためにモジュールを作成しましたが、exit 関数を書き忘れたため、モジュールが更新されるたびに新しいスレッドが作成されてしまいました。プログラムを再起動しない限り、それらのスレッドは生き続けてください。

    これは不可能です。掃除する方法を見つけなければなりません。そうしないと爆発してしまうのではないかと心配です。

    それでは、どうやって掃除すればいいのでしょうか?私が思いつくのは 2 つのステップだけです:

    クリーンアップする必要があるスレッド番号を見つけます;

    それらを破棄します;

    スレッド ID を確認する
    1. 通常のトラブルシューティングと同様に、まず ps コマンドで対象プロセスのスレッド状態を確認します。 setName、通常は対応するスレッドを参照する必要があります。次のコードを直接使用して、このスレッドをシミュレートします。

      マルチスレッドの Python バージョン
    2. #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()
      ログイン後にコピー
      ログイン後にコピー
    3. 出力:

      root@10-46-33-56:~# python t.py
      pid:  5613
      OOOOOPPPPP 139693508122368
      pid:  5613
      EEEEEEEEE 139693497632512
      ...
      ログイン後にコピー
      ログイン後にコピー
      Python で出力されたスレッド名が何であるかを確認できます。私たちはそれを設定しましたが、Ps の結果は私に人生を疑わせました:
    4. 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

    はこの問題を完全に解決できます。なぜですか?

    次の関数のドキュメントに明確に記載されているため、終了したものと開始されていないものを除く、すべてのアクティブな スレッド オブジェクト が返されます。

    [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、およびスレッド名を出力し、3 秒後に終了します。これは、スレッドの通常の終了をシミュレートするためです。

    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)
    ログイン後にコピー
    ログイン後にコピー
    Output

    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

    をこのように扱いますが、それでも引き続き考慮されます :

    もっと熱いお湯を飲みましょう,

    追伸: 熱いお湯も良いですが、8杯で十分なので、欲張らないでください。

    本題に戻りますが、上記の方法は非常に大雑把ですが、なぜそう言えるのでしょうか?

    その原理は、Python の組み込み API を使用して指定されたスレッドで例外をトリガーし、スレッドが自動的に終了できるようにするためです。 # #この方法は最後の手段として使用しないでください。一定の確率で、言いようのない問題が発生する可能性があります。覚えて!なぜ知っているのかは聞かないでください...

    スレッドを停止するのはなぜそれほど難しいのですかPython スレッドでの配置と破棄の詳細な紹介 (例付き)マルチスレッド自体は、プロセス下で協調的に同時実行できるように設計されています。スケジューリングとスレッドがプロセス リソースを共有するため、多くのロック メカニズムと状態制御が存在します。

    強制的にスレッドを強制終了すると、予期せぬバグが発生する可能性が高くなります。また、最も重要なロック リソースの解放によって、予期しない問題が発生する可能性もあります。

    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

    Ming ソースの転載についてはご注意ください: https://segmentfault.com/a/11...


    無断転載禁止
    ## #### ########################報告#####################

    • #私の記事が役に立ったと思われる場合は、お気軽に評価してください
    • 興味があるかもしれません

    ##2 コメント

                                                                                               時間の並べ替え



                                                                                               

    ### ・ 1日前###


    私だったら、-9人を殺すかもしれませんが、1人を手放すよりは誤って1000人を殺したほうがいいです、へへ

                                                                              ###いいぞ###                                                                                                                   ###返事###                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      


    ##まさか~ -9 プロセスはすべて停止しています~

                                                                                                                                                                                                                                                                                                                                                                                                                                                                         —                                                                                                                                                                                                                                                                                        著者 ### ### ・ 1日前###                                                                                                    返信を追加読み込み中...コメントをさらに表示

    ##

以上がPython スレッドでの配置と破棄の詳細な紹介 (例付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:segmentfault.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!