it-swarm.com.de

Richtige Verwendung von Mutexen in Python

Ich beginne mit Multi-Threads in python (oder zumindest ist es möglich, dass mein Skript mehrere Threads erstellt). Wäre dieser Algorithmus die richtige Verwendung eines Mutex? Ich habe dies nicht getestet Code noch und es wird wahrscheinlich nicht einmal funktionieren. Ich möchte nur, dass processData in einem Thread ausgeführt wird (einer nach dem anderen) und die main while-Schleife weiter ausgeführt wird, auch wenn sich ein Thread in der Warteschlange befindet.

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

Bearbeiten: erneutes Lesen meines Codes Ich kann sehen, dass es grob falsch ist. aber hey, deshalb bitte ich hier um hilfe.

64
Richard

Ich weiß nicht, warum Sie den Windows-Mutex anstelle von Python verwenden. Mit den Python -Methoden ist dies ziemlich einfach:

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()

Beachten Sie jedoch, dass aufgrund der Architektur von CPython (dh der Global Interpreter Lock ) ohnehin immer nur ein Thread gleichzeitig ausgeführt wird - dies ist in Ordnung, wenn mehrere davon E/A sind gebunden, obwohl Sie die Sperre so weit wie möglich aufheben möchten, damit der E/A-gebundene Thread die Ausführung anderer Threads nicht blockiert.

Eine Alternative für Python 2.6 und höher ist die Verwendung von Pythons multiprocessing -Paket. Es spiegelt das threading -Paket wider, erzeugt jedoch völlig neue Prozesse, die kann gleichzeitig ausgeführt werden. Es ist trivial, Ihr Beispiel zu aktualisieren:

from multiprocessing import Process, Lock

mutex = Lock()

def processData(data):
    with mutex:
        print('Do some stuff')

if __== '__main__':
    while True:
        p = Process(target = processData, args = (some_data,))
        p.start()
138
Chris B.

Dies ist die Lösung, die ich mir ausgedacht habe:

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

Ausgabe:

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
13
Richard

Du musst irgendwann deinen Mutex entsperren ...

Ich möchte antworte von chris-b ein bisschen mehr verbessern.

Siehe unten für meinen Code:

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

In Ihrem ersten Lauf, wenn Sie thread_safe = False In der while-Schleife wird kein Mutex verwendet, und die Threads überschreiten sich bei der Druckmethode wie folgt.

Not Thread safe

aber wenn Sie thread_safe = True und starte es, du wirst sehen, dass die Ausgabe vollkommen in Ordnung ist;

Thread safe

hoffe das hilft.

5
Teoman shipahi