copy.wait()
GILを持っていることも私の最初の疑いでした。ただし、これは私のシステムには当てはまらないようです (wait()
呼び出しは他のスレッドの進行を妨げません)。
copy.wait()
最終的にはos.waitpid()
. 後者は、私の Linux システムでは次のようになります。
PyDoc_STRVAR(posix_waitpid__doc__,
"waitpid(pid, options) -> (pid, status)\n\n\
Wait for completion of a given child process.");
static PyObject *
posix_waitpid(PyObject *self, PyObject *args)
{
pid_t pid;
int options;
WAIT_TYPE status;
WAIT_STATUS_INT(status) = 0;
if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
return NULL;
Py_BEGIN_ALLOW_THREADS
pid = waitpid(pid, &status, options);
Py_END_ALLOW_THREADS
if (pid == -1)
return posix_error();
return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
}
これにより、 POSIX でブロックされている間、明らかに GIL が解放されwaitpid
ます。
ハングしたときにプロセスにアタッチgdb
してpython
、スレッドが何をしているかを確認します。おそらく、これはいくつかのアイデアを提供するでしょう。
編集これは、マルチスレッドの Python プロセスが でどのように見えるかですgdb
:
(gdb) info threads
11 Thread 0x7f82c6462700 (LWP 30865) 0x00007f82c7676b50 in sem_wait () from /lib/libpthread.so.0
10 Thread 0x7f82c5c61700 (LWP 30866) 0x00007f82c7676b50 in sem_wait () from /lib/libpthread.so.0
9 Thread 0x7f82c5460700 (LWP 30867) 0x00007f82c7676b50 in sem_wait () from /lib/libpthread.so.0
8 Thread 0x7f82c4c5f700 (LWP 30868) 0x00007f82c7676b50 in sem_wait () from /lib/libpthread.so.0
7 Thread 0x7f82c445e700 (LWP 30869) 0x00000000004a3c37 in PyEval_EvalFrameEx ()
6 Thread 0x7f82c3c5d700 (LWP 30870) 0x00007f82c7676dcd in sem_post () from /lib/libpthread.so.0
5 Thread 0x7f82c345c700 (LWP 30871) 0x00007f82c7676b50 in sem_wait () from /lib/libpthread.so.0
4 Thread 0x7f82c2c5b700 (LWP 30872) 0x00007f82c7676b50 in sem_wait () from /lib/libpthread.so.0
3 Thread 0x7f82c245a700 (LWP 30873) 0x00007f82c7676b50 in sem_wait () from /lib/libpthread.so.0
2 Thread 0x7f82c1c59700 (LWP 30874) 0x00007f82c7676b50 in sem_wait () from /lib/libpthread.so.0
* 1 Thread 0x7f82c7a7c700 (LWP 30864) 0x00007f82c7676b50 in sem_wait () from /lib/libpthread.so.0
ここでは、2 つを除くすべてのスレッドが GIL を待機しています。典型的なスタック トレースは次のようになります。
(gdb) thread 11
[Switching to thread 11 (Thread 0x7f82c6462700 (LWP 30865))] #0 0x00007f82c7676b50 in sem_wait () from /lib/libpthread.so.0
(gdb) where
#0 0x00007f82c7676b50 in sem_wait () from /lib/libpthread.so.0
#1 0x00000000004d4498 in PyThread_acquire_lock ()
#2 0x00000000004a2f3f in PyEval_EvalFrameEx ()
#3 0x00000000004a9671 in PyEval_EvalCodeEx ()
...
どのスレッドがどれであるかはhex(t.ident)
、Python コードで表示することでわかります。どこt
にthreading.Thread
オブジェクトがありますか。gdb
私のシステムでは、これは( 0x7f82c6462700
et al)に見られるスレッド ID と一致します。