Juist gebruik van mutexen in Python

Ik begin met multi-threads in python (of het is tenminste mogelijk dat mijn script meerdere threads maakt). zou dit algoritme het juiste gebruik van een Mutex zijn? Ik heb deze code nog niet getest en het zal waarschijnlijk niet eens werken. Ik wil gewoon dat processData in een thread wordt uitgevoerd (een voor een) en dat de main while-lus blijft draaien, zelfs als er een thread in de wachtrij staat.

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

Bewerken: als ik mijn code opnieuw lees, zie ik dat deze totaal verkeerd is. maar goed, daarom vraag ik hier om hulp.


Antwoord 1, autoriteit 100%

Ik weet niet waarom je de Mutex van Window gebruikt in plaats van die van Python. Met behulp van de Python-methoden is dit vrij eenvoudig:

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

Maar let op, vanwege de architectuur van CPython (namelijk het Global Interpreter Lock) er zal in feite toch maar één thread tegelijk worden uitgevoerd – dit is prima als een aantal van hen I / O-gebonden is, hoewel u de vergrendeling zo veel mogelijk wilt ontgrendelen, zodat de I / O-gebonden thread dat niet doet voorkom dat andere discussielijnen worden uitgevoerd.

Een alternatief voor Python 2.6 en hoger is het gebruik van het multiprocessing-pakket van Python. Het weerspiegelt het threadingpakket, maar zal geheel nieuwe processen creëren die kunnengelijktijdig draaien. Het is triviaal om uw voorbeeld bij te werken:

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

Antwoord 2, autoriteit 8%

Dit is de oplossing die ik bedacht:

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

Uitvoer:

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

Antwoord 3, autoriteit 7%

Ik wil graag antwoordvan chris-b
een beetje meer.

Zie hieronder voor mijn 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

Als u bij uw eerste run thread_safe = Falseinstelt in while-lus, zal mutex niet worden gebruikt en zullen threads over elkaar heen stappen in de afdrukmethode zoals hieronder;

Niet veilig voor threads

maar, als je thread_safe = Trueinstelt en het uitvoert, zul je zien dat alle uitvoer perfect in orde is;

Draadveilig

hoop dat dit helpt.


Antwoord 4, autoriteit 6%

Je moet je Mutex ooit ontgrendelen…

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Other episodes