Подтвердить что ты не робот

Семафоры на 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. Как перемещать отпечатки?

4b9b3361

Ответ 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()

Ответ 2

Вы также можете использовать метод 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()

[ПРИМЕЧАНИЕ]:

Кроме того, разница между мьютексом, семафором и блокировкой

Ответ 3

Я использовал этот код, чтобы продемонстрировать, как 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