Semaphores on Python
It is working fine, its just that its printing too fast for you to see . Try putting a time.sleep()
in both functions (a small amount) to sleep the thread for that much amount of time, to actually be able to see both 1 as well as 2.
Example -
import threadingimport timesem = 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()
Also, you can use Lock/mutex method as follows:
import threadingimport timemutex = threading.Lock() # is equal to threading.Semaphore(1)def fun1(): while True: mutex.acquire() print(1) mutex.release() time.sleep(.5)def fun2(): while True: mutex.acquire() print(2) mutex.release() time.sleep(.5)t1 = threading.Thread(target=fun1).start()t2 = threading.Thread(target=fun2).start()
Simpler style using "with
":
import threadingimport timemutex = threading.Lock() # is equal to threading.Semaphore(1)def fun1(): while True: with mutex: print(1) time.sleep(.5)def fun2(): while True: with mutex: print(2) time.sleep(.5)t1 = threading.Thread(target=fun1).start()t2 = threading.Thread(target=fun2).start()
[NOTE]:
In fact, I want to find asyncio.Semaphores
, not threading.Semaphore
,and I believe someone may want it too.
So, I decided to share the asyncio.Semaphores
, hope you don't mind.
from asyncio import ( Task, Semaphore,)import asynciofrom typing import Listasync 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())
output
shoppingcodingshoppingcodingshoppingcodingshoppingcodingshoppingcodingshoppingcodingshoppingcodingshoppingcoding
16*0.25 = 2