PyThread_acquire_lock - проблемы с получением ключа

Я пишу многопоточное приложение на Python.

Основной поток создает пул потоков из 5 рабочих потоков. Основной поток также создает поток мониторинга.

Всего: 6 тем + 1 Основная тема = 7

Все потоки общаются с сервером MySQL (mysqldb -> libmysqlclient_r)

В моей оболочке SQL я добавил Threading.Lock в функцию запроса БД. Эта блокировка является глобальной блокировкой, и все потоки, которые запрашивают БД, используют ее.

def query(self, query):
  with lock:
   execute Query Here

Все работает хорошо, пока в какой-то момент основной поток не застрял (как и все потоки), я подключил отладчик GDB и заметил, что: (информационные потоки)

  7 Thread 0x7f555c386700 (LWP 16077)  0x00007f5561a503c0 in sem_wait () from /lib/libpthread.so.0
  6 Thread 0x7f555bb85700 (LWP 16078)  0x00007f5561a503c0 in sem_wait () from /lib/libpthread.so.0
  5 Thread 0x7f555b384700 (LWP 16079)  0x00007f5561a503c0 in sem_wait () from /lib/libpthread.so.0
  4 Thread 0x7f555ab83700 (LWP 16080)  0x00007f5561a503c0 in sem_wait () from /lib/libpthread.so.0
  3 Thread 0x7f555a382700 (LWP 16081)  0x00007f5561a503c0 in sem_wait () from /lib/libpthread.so.0
  2 Thread 0x7f5559b81700 (LWP 16083)  0x00007f55609141a3 in select () from /lib/libc.so.6
  1 Thread 0x7f5561e6f700 (LWP 16061)  0x00007f5561a503c0 in sem_wait () from /lib/libpthread.so.0

Th1 = основная резьба, Th2 = контрольная резьба, Th3-Th7 - рабочие резьбы

Я заметил, что все потоки рядом с потоком монитора ожидают sem_wait():

(gdb) bt
#0  0x00007f5561a503c0 in **sem_wait** () from /lib/libpthread.so.0
#1  0x00000000004d44e8 in **PyThread_acquire_lock** ()
#2  0x00000000004d8982 in ?? ()
#3  0x00000000004a7ba5 in PyEval_EvalFrameEx ()

Тем не менее, поток монитора способен получить и снять блокировку (он запускается каждые 30 секунд, вы видите, что select() происходит из-за режима сна (30)). Я не понимаю, почему остальные потоки застряли в sem_wait(), так как никто не получил блокировку.

Есть идеи как решить это? как это отладить?

Спасибо

1 ответ

Решение

Кажется, что я использовал одно и то же соединение, используя несколько потоков, что по DOCS запрещено.

Совет: убедитесь, что каждый поток имеет свой собственный объект подключения.

Другие вопросы по тегам