Блокировка и очередь многопроцессорной обработки Python, не работающие на более старом ядре Linux

#python-3.x #linux #locking #posix #yocto

#python-3.x #linux #блокировка #posix #yocto

Вопрос:

У меня есть машина реального времени под управлением 32-битного Linux с ядром 4.9.124-rt94-rc1-mx6-sr g79f5711, созданная с помощью проекта Yocto. И вторая, более старая машина, работающая под управлением 32-битного Linux с ядром стандарта 3.18.48-rt54-yocto, также созданная с помощью проекта Yocto.

У меня есть 2 коротких скрипта на Python. первый:

 from multiprocessing import Queue, Lock

if __name__ == "__main__":
    flag_lock = Lock()
     
    flag_lock.acquire()
    flag_lock.release()
  

И второй:

 import multiprocessing as mp
if __name__ == "__main__":
    test = mp.Queue()
    print("hello")
    test.put(3)
    print("world")
  

Оба этих сценария отлично работают на более новой машине с ядром 4.9.124-rt94-rc1-mx6-sr g79f5711

Выполнение первого сценария на компьютере со старым ядром вызовет исключение:

Обратная трассировка (последний последний вызов): Файл «./temp_lock.py «, строка 8, в flag_lock.release() Ошибка значения: семафор или блокировка, выпущенные слишком много раз

Выполнение второго скрипта на компьютере со старым ядром напечатает «привет» и застрянет на неопределенный срок в test.put(3).

Учитывая, что очередь потокобезопасна, я предполагаю, что какой-то механизм блокировки в ней выходит из строя.

Я использовал python 3.6.0 и python 3.8.3 для выполнения этих сценариев с одинаковыми результатами на обеих машинах.

Я использовал strace в первом скрипте (с блокировкой), и основное отличие, которое я обнаружил, заключается в том, что на более старой машине ioctl (3, TCGETS, 0xbfe94f4c) = -1 ENOTTY (неподходящий ioctl для устройства) продолжает сбой 57 раз.

Я также заметил, что вызывается fstat64(), из этого я делаю вывод, что внедрение блокировок в многопроцессорный модуль является POSIX

Ответ №1:

Я заменил многопроцессорную библиотеку библиотекой потоков, и теперь все проблемы с блокировкой и очередью решены, и код выполняется на более старом ядре так же, как и на более новом.

Я все еще не могу объяснить, в чем разница под капотом и почему многопроцессорность.Очередь и многопроцессорность.Блокировка отлично работает на более новом ядре, но не на более старом.