Python上的信号量

时间:2015-07-20 03:48:15

标签: python semaphore

我几周前开始使用Python进行编程,并尝试使用Semaphores同步两个简单的线程,用于学习目的。这就是我所拥有的:

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年。如何对印刷品进行间隔缩放?

4 个答案:

答案 0 :(得分:9)

工作正常,只是它的打印速度太快,你无法看到。尝试在两个函数(少量)中放置一个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()

答案 1 :(得分:1)

您还可以使用锁定/互斥方法,如下所示:

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

注意:另外difference between mutex and semaphoremutex VS semaphore

答案 2 :(得分:0)

我使用此代码演示了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

答案 3 :(得分:0)

实际上,我想找到DataFrame.loc,而不是threading.Semaphore, 而且我相信有人可能也会想要。

所以,我决定分享 asyncio。 Semaphores,希望您不要介意。

from asyncio import (
    Task,
    Semaphore,
)
import asyncio
from typing import List


async def shopping(sem: Semaphore):
    while True:
        async with sem:
            print(shopping.__name__)
        await asyncio.sleep(0.25)  # Transfer control to the loop, and it will assign another job (is idle) to run.


async def coding(sem: Semaphore):
    while True:
        async with sem:
            print(coding.__name__)
        await asyncio.sleep(0.25)


async def main():
    sem = Semaphore(value=1)
    list_task: List[Task] = [asyncio.create_task(_coroutine(sem)) for _coroutine in (shopping, coding)]
    """ 
    # Normally, we will wait until all the task has done, but that is impossible in your case.
    for task in list_task:
        await task
    """
    await asyncio.sleep(2)  # So, I let the main loop wait for 2 seconds, then close the program.


asyncio.run(main())

输出

shopping
coding
shopping
coding
shopping
coding
shopping
coding
shopping
coding
shopping
coding
shopping
coding
shopping
coding

16 * 0.25 = 2