python الدوال - الاستخدام السليم للطعنات في بايثون




اكواد جاهزة (5)

لا أعلم لماذا أنت تستخدم نافذة موتكس بدلاً من بايثون. باستخدام أساليب بايثون ، هذا بسيط للغاية:

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 (وبالتحديد قفل المترجم العالمي ) ، سيكون لديك فعليًا مؤشر واحد فقط يعمل في وقت واحد - على أية حال ، إذا كان عددهم I / O مرتبطًا ، على الرغم من أنك تريد لتحرير القفل قدر الإمكان بحيث لا يمنع مؤشر ترابط I / O منضم مؤشرات الترابط الأخرى من التشغيل.

بديل ، بالنسبة إلى Python 2.6 وما بعده ، هو استخدام حزمة multiprocessing لـ Python. إنه يعكس حزمة 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()

أنا بدأت مع موضوع متعدد في الثعبان (أو على الأقل أنه من الممكن أن البرنامج النصي الخاص بي يخلق خيوط متعددة). هل ستكون هذه الخوارزمية هي الاستخدام الصحيح لموتكس؟ لم أختبر هذا الرمز بعد ، وربما لن يعمل. أريد فقط processData للتشغيل في مؤشر ترابط (واحد في وقت) والحلقة الرئيسية أثناء الاستمرار في التشغيل ، حتى إذا كان هناك مؤشر ترابط في قائمة الانتظار.

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

تعديل: إعادة قراءة الرمز الخاص بي أستطيع أن أرى أنه خطأ فادح. ولكن هذا هو السبب في أنني هنا أطلب المساعدة.


عليك أن تطلق جهاز موتكس في وقت ما ...


أود تحسين answer من أكثر قليلاً.

انظر أدناه للحصول على الرمز الخاص بي:

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 في أثناء التكرار ، لن يتم استخدام كائن المزامنة ، وسوف تتخطى مؤشرات الترابط بعضها البعض في طريقة الطباعة على النحو التالي ؛

ولكن ، إذا قمت بتعيين thread_safe = True وقم بتشغيله ، فسوف ترى كل الإخراج يأتي بشكل جيد ؛

أتمنى أن يساعدك هذا.


هذا هو الحل الذي توصلت إليه:

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

index() إرجاع فهرس القيمة الأول!

| فهرس(...)
| L.index (القيمة ، [start ، [stop]]) -> integer - return first index of value

def all_indices(value, qlist):
    indices = []
    idx = -1
    while True:
        try:
            idx = qlist.index(value, idx+1)
            indices.append(idx)
        except ValueError:
            break
    return indices

all_indices("foo", ["foo","bar","baz","foo"])




python multithreading mutex