2015-07-20 82 views
4

幾周前我開始用Python進行編程,並試圖使用信號量來同步兩個簡單的線程,用於學習目的。這裏是我得到的:Python上的信號量

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。我怎樣才能對印刷品進行中間縮放?

回答

2

它工作正常,只是它的打印速度太快,你看不到。嘗試把兩種功能的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() 
+0

Thx尋求幫助,但是我發現了真正的問題,因爲我在兩個線程中都使用相同的信號量,第一個信號幾乎立即完成,因此第二個信號無法獲得鎖定並執行。 –

+0

@VictorTurrisi如果你輸入一個大範圍並運行你的程序,然後將輸出重定向到一個文件然後檢查該文件,你可能會看到「2」確實被打印出來,但是,它像很多1,然後很多2,然後又是很多1,等等。這是因爲它執行得太快,你需要在它們之間放置一個'time.sleep()'來看它們是否一個接一個地執行。 –

0

我使用此代碼來演示1線程如何使用Semaphore,另一個線程將等待(非阻塞),直到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 
0

您還可以使用鎖定/互斥方法如下:

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

注: additionaly difference between mutex and semaphoremutex VS semaphore