It sounds to me like they are leading you toward a semaphore solution. Semaphores are used to signal another thread that it's their turn. They are used much less frequently than mutexes, which I guess is why they think it's a good interview question. It's also why the example seems contrived.
Basically, you would create m
semaphores. Each thread x
waits on semaphore x
then posts to semaphore x+1
after doing its thing. In pseudocode:
loop:
wait(semaphore[x])
if no more words:
post(semaphore[(x+1) % m])
exit
print word
increment current word pointer
post(semaphore[(x+1) % m])
Using a dict let's you translate the key into a callable. The key doesn't need to be hardcoded though, as in your example.
Usually, this is a form of caller dispatch, where you use the value of a variable to connect to a function. Say a network process sends you command codes, a dispatch mapping lets you translate the command codes easily into executable code:
def do_ping(self, arg):
return 'Pong, {0}!'.format(arg)
def do_ls(self, arg):
return '\n'.join(os.listdir(arg))
dispatch = {
'ping': do_ping,
'ls': do_ls,
}
def process_network_command(command, arg):
send(dispatch[command](arg))
Note that what function we call now depends entirely on what the value is of command
. The key doesn't have to match either; it doesn't even have to be a string, you could use anything that can be used as a key, and fits your specific application.
Using a dispatch method is safer than other techniques, such as eval()
, as it limits the commands allowable to what you defined beforehand. No attacker is going to sneak a ls)"; DROP TABLE Students; --
injection past a dispatch table, for example.
Best Answer
Barriers are used to make multiple threads within the same program do something in a synchronized fashion.
The real-world analog would be the starting gate at a horse race. Ten horses in a race won't arrive at the gate at the same time, but it isn't until all ten of them have entered the gate and are ready to race does the gate open and each horse starts its race. (Starting gates are also called starting barriers because they were barriers rather than gates, which might be where the threading construct got its name.)
Threading's barrier does the same thing. In a system where each thread has a function and all must be ready before any starts operating, the way to enforce that is have the threads initialize and then meet at a barrier. You might see this in the system that runs the engine in your car, where the thread overseeing ignition wouldn't want to operate until it can be sure the threads that handle the throttle and crank position sensors are ready to provide useful data.