Even using a traffic light, I face block repetition. Why and how to avoid?

Asked

Viewed 55 times

0

So, I have a code that I put a semaphore, thus avoiding overlap in the print, but I notice some strange occurrences of the same while. Why does this happen? There are ways to avoid?

import threading
import time

sem = threading.Semaphore()
number = 0

def primeira():
    global number
    while True:
        number += 1        
        sem.acquire()
        print(f'P1: {number}')
        sem.release()
        time.sleep(1)


def segunda():
    global number
    while True:
        sem.acquire()
        number += 1
        print(f'P2: {number}')
        sem.release()
        time.sleep(1)


td1 = threading.Thread(target=primeira)
td2 = threading.Thread(target=segunda)

td1.start()
td2.start()

td1.join()
td2.join()

I realize that when running, sometimes P1 or P2 are executed/printed twice and yet they maintain the integrity of the order of numbers.

Example:

P1: 1
P2: 2
P1: 3
P2: 4  // Aqui
P2: 5  //
P1: 6
P2: 7
P1: 8  // Aqui
P1: 9  //
P2: 10

I also realize that by decreasing the time of sleep, this repetition occurs more often, but never more than 2 times, as in the example. Why? There is a simple way to avoid it?

  • 2

    Just so we’re clear, you hoped you’d always change one thread to the other?

  • Yes, exactly this: P1 -> P2 -> P1.... I’m seeing the documentation for asyncio locks, seems to be the 'right' way to do, but I’m not getting to apply.

  • 1

    Yeah, about Lock, that’s pretty much it, yeah, the premise is that it’s wrong. There is no guarantee in the order of which thread will run and acquire control of Lock, so P2 can release the lock and immediately acquire it again. Who deals with this is the operating system and it does not even make sense to want to define the order of execution, because if you need to keep the order, can do in the same thread

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.