Правильное использование мьютексов в Python
Я начинаю с нескольких потоков в Python (или, по крайней мере, возможно, что мой скрипт создает несколько потоков). будет ли этот алгоритм правильным использованием мьютекса? Я еще не тестировал этот код, и он, вероятно, даже не будет работать. Я просто хочу, чтобы processData выполнялась в потоке (по одному), а основной цикл while продолжал работать, даже если есть поток в очереди.
from threading import Thread
from win32event import CreateMutex
mutex = CreateMutex(None, False, "My Crazy Mutex")
while(1)
t = Thread(target=self.processData, args=(some_data,))
t.start()
mutex.lock()
def processData(self, data)
while(1)
if mutex.test() == False:
do some stuff
break
Edit: перечитывая мой код, я вижу, что это грубо неправильно. но эй, вот почему я здесь просьба о помощи.
4 ответов:
Я не знаю, почему вы используете мьютекс окна вместо питона. Используя методы Python, это довольно просто:
from threading import Thread, Lock mutex = Lock() def processData(data): mutex.acquire() try: print('Do some stuff') finally: mutex.release() while True: t = Thread(target = processData, args = (some_data,)) t.start()но обратите внимание, из-за архитектуры CPython (а именно Глобальная Переводчик Замок) вы будете эффективно работать только с одним потоком за раз-это нормально, если несколько из них связаны с вводом-выводом, хотя вы захотите освободить блокировку как можно больше, чтобы связанный поток ввода-вывода не блокировал другие потоки бегущий.
альтернативой для Python 2.6 и более поздних версий является использование Python
multiprocessingпакета. Он отражаетthreadingпакет, но создаст совершенно новые процессы, которые можете запустить одновременно. Это тривиально, чтобы обновить ваш пример:from multiprocessing import Process, Lock mutex = Lock() def processData(data): with mutex: print('Do some stuff') if __name__ == '__main__': while True: p = Process(target = processData, args = (some_data,)) p.start()
это решение я придумал:
import time from threading import Thread from threading import Lock def myfunc(i, mutex): mutex.acquire(1) time.sleep(1) print "Thread: %d" %i mutex.release() mutex = Lock() for i in range(0,10): t = Thread(target=myfunc, args=(i,mutex)) t.start() print "main loop %d" %iвыход:
main loop 0 main loop 1 main loop 2 main loop 3 main loop 4 main loop 5 main loop 6 main loop 7 main loop 8 main loop 9 Thread: 0 Thread: 1 Thread: 2 Thread: 3 Thread: 4 Thread: 5 Thread: 6 Thread: 7 Thread: 8 Thread: 9
Я хотел бы улучшить ответ С Крис-б еще немного.
ниже мой код:
from threading import Thread, Lock import threading mutex = Lock() def processData(data, thread_safe): if thread_safe: mutex.acquire() try: thread_id = threading.get_ident() print('\nProcessing data:', data, "ThreadId:", thread_id) finally: if thread_safe: mutex.release() counter = 0 max_run = 100 thread_safe = False while True: some_data = counter t = Thread(target=processData, args=(some_data, thread_safe)) t.start() counter = counter + 1 if counter >= max_run: breakв вашем первом запуске, если вы установите
thread_safe = Falseв цикле while мьютекс не будет использоваться, и потоки будут перешагивать друг через друга в методе печати, как показано ниже;но, если вы установите
thread_safe = Trueи запустите его, вы увидите все, на выходе получается идеально отлично;надеюсь, что это помогает.


Comments