Когда нам нужно запустить многопоточное приложение glfw, программа остановится, если в MainProcess был вызван glfw.create_window()
.
Это в основном часть гораздо большего кода, где я не могу изменить архитектуру (включая многопроцессорную архитектуру), но это минимальный код, который может воспроизвести ошибку.
- Операционная система: Linux Ubuntu 16.04 (Xenial)
- Python Версия: 3.6
from multiprocessing import Process, Pipe
import threading, multiprocessing
import glfw
def worker():
print("[Thread]:", threading.get_ident(), "[Process]:", multiprocessing.current_process())
glfw.init()
glfw.window_hint(glfw.VISIBLE, 0)
glfw.window_hint(glfw.DOUBLEBUFFER, 0)
context = glfw.create_window(width=640, height=480, title='Invisible window', monitor=None, share=None)
print("Window was created successfully!")
if __name__ == "__main__":
## Uncomment the following line to see the program halt with errors:
# worker()
np = 10
processes = [Process(target=worker) for i in range(np)]
for p in processes:
p.daemon = True
p.start()
print("LET'S WAIT FOR A LONG TIME!")
import time
time.sleep(1000)
Первый
Если я не вызову glfw.create_window
в основном процессе, код будет работать нормально. Но если я вызову его до запуска других процессов (вы можете раскомментировать # worker()
, чтобы увидеть этот эффект), это вызовет следующую ошибку (я скопировал вывод только частично):
...
XIO: fatal IO error 25 (Inappropriate ioctl for device) on X server ":0"
after 192 requests (192 known processed) with 15 events remaining.
[xcb] Unknown sequence number while processing queue
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
python: ../../src/xcb_io.c:274: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed.
XIO: fatal IO error 25 (Inappropriate ioctl for device) on X server ":0"
after 192 requests (192 known processed) with 15 events remaining.
XIO: fatal IO error 25 (Inappropriate ioctl for device) on X server ":0"
...
Второй :
В случае, когда # worker()
все еще комментируется, glfw.init()
должен быть внутри функции worker
и не может быть вызван только один раз глобально, то есть до функции worker
. Почему это так?