How to trigger a thread to start working using semaphore?
When using semaphores or locks, you don't do anything else than acquiring the semaphore (resp. the lock), and then do what you want.  For example, if you want to use a lock, then you typically have two threads

# thread 1
lock.acquire()
# here is all the work for thread 1
lock.release()


and the other thread is completely identical:

# thread 2
lock.acquire()
# here is all the work for thread 2
lock.release()


Now, the first to obtain the lock gets to run the code first, and the other thread needs to wait until the lock is released.

Here's an example of a Python program that prints a series of 0s and 1s depending on the order of execution:

import time
import threading

lock = threading.Lock()
lst = []


def f1():
    for i in range(10):
        lock.acquire()
        lst.append("0")
        lock.release()
        time.sleep(0.1)


def f2():
    for i in range(10):
        lock.acquire()
        lst.append("1")
        lock.release()
        time.sleep(0.1)


t1 = threading.Thread(target=f1)
t2 = threading.Thread(target=f2)
t1.start()
t2.start()
t1.join()
t2.join()

print("".join(lst))



Feel free to run it in your own terminal.

(Note that I used lock.acquire() and lock.release(), but the "correct" way is to use a context manager and use with lock: ....)

See also:  Lock, mutex, semaphore… what's the difference?