0

In POSIX and Windows API have barriers that allow synchronizing n threads. When n threads waiting for the barrier they may proceed doing some work.

What I want is for threads to wait for a set of barriers. When any of the barriers have n threads waiting it unlocks, returning which one of the barriers that was unlocked. Looking at POSIX and Windows API this is not a part of the native API. Is there another way around it?

Target language is C/C++ but language agnostic solutions are also appreciated.

Bakground: I´m looking into CSP, the basis of Occam and an inspiration source for Go. I believe a runtime can treat Events as barriers. However that would require some way of waiting for multiple barriers. I´d like to getting around this without major effort put in a supervisor.


Edit: Making an example in CSP notation.

P = c -> c -> d -> P;
Q = d -> e -> Q;
R = c -> R | d -> SKIP;
RUNTIME = P || Q || R;

For those of you unfamiliar with the syntax, P is a process (thread) interacting with event c, then c again, then d, then works like P. Q works similar. R is defined as c then R or d then SKIP. RUNTIME is the concurrent process made from P, Q and R.

Events are synchronized similar to barriers; all processes must be able to deal with it at the same time for it to happen. The trick is that a process may be able to participate in a set of event such as R which may participate in c or d, but unable to because of other processes (P and Q) not being able to participate.

This is where the "wait for ANY from a SET of barriers" comes in. R may wait for c or d simultaneously, and depending on which one is unlocked will behave differently.

Andreas
  • 5,086
  • 3
  • 16
  • 36
  • i haven't understood what you need, honestly. – Federico Sep 25 '17 at 15:57
  • @Federico what is not to understand? a thread waits for a SINGLE barrier as of POSIX and Windows API. I want it to wait for ANY barrier in a SET of barriers. How is this not clear??? – Andreas Sep 25 '17 at 16:08
  • What's the use case? Using a single thread to wait for any one of several different events runs counter to the core idea of threads which is, to simplify the logic of a program by having a separate thread to wait for each different thing that a program needs to wait for. – Solomon Slow Sep 25 '17 at 16:40
  • 1
    One workaround would be, for each barrier, create a thread that awaits that barrier and then puts a token into a common, blocking queue. Then, a thread that wants to wait for _any_ barrier can do so by waiting to remove the token from the queue. – Solomon Slow Sep 25 '17 at 16:42
  • @Andreas What's the obstacle to coding what you need using mutexes and condition variables (or events)? Do you not know how to do it? Or is there some reason that obvious solution wouldn't work for you? – David Schwartz Sep 25 '17 at 16:47
  • @jameslarge added a theoretical use case. – Andreas Sep 25 '17 at 16:47
  • @DavidSchwartz I´m defining (or at least try defining) a minimalistic runtime environment for CSP using widely accessible and understood synchronization primitives. The barriers are SO close to what I need so I hoped someone had a trick taking that final step. – Andreas Sep 25 '17 at 16:52
  • 1
    Use one lock. Inside the lock, put all the containers, state-variables, booleans arrays, counters, whatever you need to implement whatever it is you want to do. All threads enter. They either leave immediately and run on or leave and immediately block on an event/semaphore, ether a private one, or one they got from inside the lock, whatever is needed. Threads in the lock can examine, iterate, increment, decrement, whatever they want 'cos they're inside the lock. They can also signal any events/semas that threads are waiting on outside the lock. Bulid whatever you want from that framework. – Martin James Sep 25 '17 at 16:54
  • The tricks (as suggested by james large) are ugly. But they'll work. Otherwise, code what you need as Martin James suggests. – David Schwartz Sep 25 '17 at 16:56
  • @jameslarge Nice one! I´ll have to double-check but looks like you win. – Andreas Sep 25 '17 at 16:57
  • 1
    Actually, choice three is to re-architect so that this requirement goes away. Whether or not that's possible depends on details of the specific problem. That may or may not be an option in your case. – David Schwartz Sep 25 '17 at 16:58
  • @DavidSchwartz I´m making a CSP model runtime. I can´t make the requirement go away unless redefining CSP. But I agree on your comments as advice to others able to use an alternative architecture. – Andreas Sep 25 '17 at 17:05
  • ^^ What @DavidSchwartz says. Solving complex requirements by designing away the need for them is a good plan on any system, but especially so with multithreading. So many devs get themselves tied up in horrible knots with bad designs, (eg. https://stackoverflow.com/q/46400868/758133). – Martin James Sep 25 '17 at 17:06
  • @MartinJames Ironically what I´m implementing is a simpler way of dealing with concurrency :-) So in a sense once I got this working I can make a model of the runtime and prove the design to be not only good, but perfect. All your multithreaded fears shall be moot and void! – Andreas Sep 25 '17 at 17:08
  • @Andreas 'design to be not only good, but perfect'... well, good luck with that one;) I don't with to put anyone off - it's just that it seems, when it comes to multithreading, I spend most time advising devs to not do something because it will end badly, rather than 'do this' advice. It's kinda weird what people pick up from the dodgy websites:( – Martin James Sep 25 '17 at 17:16
  • FWIW: A `Semaphore` is functionally equivalent to a blocking queue of tokens if the tokens are indistinguishable from one another. The number of "permits" in the semaphore is equivalent to the number of tokens in the queue. – Solomon Slow Sep 25 '17 at 17:21
  • @jameslarge Good point. That reminds of a prerequisite: when unblocked the blocking primitive must be reset to its original n count. Semaphores don´t have this property natively, barriers do. I like you first suggestion better but if I get the time I´ll make answers from both suggestions. – Andreas Sep 25 '17 at 17:28

0 Answers0