私は数週間前にプログラミングを始めましたPython=学習目的で、セマフォを使用して2つの単純なスレッドを同期しようとしていました。
import threading
sem = threading.Semaphore()
def fun1():
while True:
sem.acquire()
print(1)
sem.release()
def fun2():
while True:
sem.acquire()
print(2)
sem.release()
t = threading.Thread(target = fun1)
t.start()
t2 = threading.Thread(target = fun2)
t2.start()
しかし、それは1だけを印刷し続けます。どうすればプリントを挿入できますか?
正常に動作していますが、印刷するには速すぎて見えません。両方の関数(少量)にtime.sleep()
を入れて、その時間だけスレッドをスリープさせ、実際に1と2の両方を見ることができるようにしてください。
例-
import threading
import time
sem = threading.Semaphore()
def fun1():
while True:
sem.acquire()
print(1)
sem.release()
time.sleep(0.25)
def fun2():
while True:
sem.acquire()
print(2)
sem.release()
time.sleep(0.25)
t = threading.Thread(target = fun1)
t.start()
t2 = threading.Thread(target = fun2)
t2.start()
次のようにLock/mutexメソッドを使用することもできます:
import threading
import time
mutex = threading.Lock() # equal to threading.Semaphore(1)
def fun1():
while True:
mutex.acquire()
print(1)
mutex.release()
time.sleep(0.5)
def fun2():
while True:
mutex.acquire()
print(2)
mutex.release()
time.sleep(0.5)
t1 = threading.Thread(target=fun1).start()
t2 = threading.Thread(target=fun2).start()
別の/簡単な使用タイプ:
import threading
import time
mutex = threading.Lock() # equal to threading.Semaphore(1)
def fun1():
while True:
with mutex:
print(1)
time.sleep(0.5)
def fun2():
while True:
with mutex:
print(2)
time.sleep(0.5)
t1 = threading.Thread(target=fun1).start()
t2 = threading.Thread(target=fun2).start()
注:追加 ミューテックスとセマフォの違い 、 ミューテックスVSセマフォ
このコードを使用して、1つのスレッドがセマフォを使用し、他のスレッドがSempahoreが使用可能になるまで待機(非ブロッキング)する方法を示しました。
これはPython3.6を使用して記述されました。他のバージョンではテストされていません。
これは、同期が同じスレッドから行われている場合にのみ機能します。IPC別のプロセスからこのメカニズムを使用すると失敗します。
import threading
from time import sleep
sem = threading.Semaphore()
def fun1():
print("fun1 starting")
sem.acquire()
for loop in range(1,5):
print("Fun1 Working {}".format(loop))
sleep(1)
sem.release()
print("fun1 finished")
def fun2():
print("fun2 starting")
while not sem.acquire(blocking=False):
print("Fun2 No Semaphore available")
sleep(1)
else:
print("Got Semphore")
for loop in range(1, 5):
print("Fun2 Working {}".format(loop))
sleep(1)
sem.release()
t1 = threading.Thread(target = fun1)
t2 = threading.Thread(target = fun2)
t1.start()
t2.start()
t1.join()
t2.join()
print("All Threads done Exiting")
これを実行すると、次の出力が得られます。
fun1 starting
Fun1 Working 1
fun2 starting
Fun2 No Semaphore available
Fun1 Working 2
Fun2 No Semaphore available
Fun1 Working 3
Fun2 No Semaphore available
Fun1 Working 4
Fun2 No Semaphore available
fun1 finished
Got Semphore
Fun2 Working 1
Fun2 Working 2
Fun2 Working 3
Fun2 Working 4
All Threads done Exiting