-1

Given a situation where thread A had to dispatch work to thread B, is there any synchronisation mechanism that allows thread A to not return, but remain usable for other tasks, until thread B is done, of which then thread A can return?

This is not language specific, but simple c language would be a great choice in responding to this.

This could be absolutely counterintuitive; it actually sounds as such, but I have to ask before presuming...

Please Note This is a made up hypothetical situation that I'm interested in. I am not looking for a solution to an existing problem, so alternative concurrency solutions are completely pointless. I have no code for it, and if I were in it I can think of a few alternative code engineering solutions to avoid this setup. I just wish to know if a thread can be usable, in some way, while waiting for a signal from another thread, and what synchronisation mechanism to use for that.


UPDATE

As I mentioned above, I know how to synchronise threads etc. Im only interested in the situation that I have presented here. Mutexes, semaphores and locks all kinds of mechanisms will all synchronise access to resources, synchronise order of events, synchronise all kinds of concurrently issues, yes. But Im not interested in how to do it properly. I just have this made up situation that I wish to know if it can be addressed with a mechanism as described prior.


UPDATE 2

It seems I have opened up a portal for people that think they are experts in concurrency to teleport and lecture at chance how they think the rest of world does not know how threading works. I simply asked if there is a mechanism for this situation, not a work around solution, not 'the proper way to synchronise', not a better way to do it. I already know what I would do and never be in this made up situation. It's simply hypothetical.

pnizzle
  • 6,243
  • 4
  • 52
  • 81
  • Specify your programming language please. Threading mechanisms are typically language-specific. – Robert Harvey Dec 18 '18 at 23:26
  • What do you mean by "waiting" exactly? Because the usual definition of "waiting" is not doing anything until something happens. In what sense is a thread waiting for something if it's doing something else? – David Schwartz Dec 18 '18 at 23:30
  • @DavidSchwartz its working, but at the same time listening for a signal. Im quite sure this is possible on a low level – pnizzle Dec 19 '18 at 00:39
  • But what does that mean though? If the signal occurs, what happens to the thread? Is it interrupted? Does it check for the signal periodically? Or what? – David Schwartz Dec 19 '18 at 00:52
  • @DavidSchwartz that's what im interesting in knowing. I want to know if there is any default mechanism that does that, a semaphore, a lock of some sort, something. Or if one would have to write up something that does all that (what you mentioned) under the covers – pnizzle Dec 19 '18 at 01:00
  • That does what exactly though? Allows one thread to check if another thread has done something? That's trivial -- mutexes allow you to do that. – David Schwartz Dec 19 '18 at 01:01
  • @DavidSchwartz and yes, when the signal comes up, or is satisfied (whatever the word that applies), then the thread can be interrupted, or it continues from its waiting point, in its next cycle or what ever. – pnizzle Dec 19 '18 at 01:02
  • That exactly what mutexes do. They allow one thread to set some value somewhere (that can mean "the work is done") and then another thread can check that value whenever it wants. If you want to be able to wait for something, you can use events or condition variables. Basically, just learn about thread synchronization -- there's a whole toolbox that lets you do things like this easily. If you want a job queue that provides this, I'd just search for a C implementation of a job queue that lets you cancel, check on, or wait for jobs. – David Schwartz Dec 19 '18 at 01:03
  • @DavidSchwartz yes mutexs can be used for synchronisation. But can a thread that is waiting on a code section protected by a mutex be used for other tasks until that section is opened up? That is impossible with a mutex. But is it possible with another mechanism? That Sir, is my question – pnizzle Dec 19 '18 at 01:05
  • @DavidSchwartz please read the comment I made on your answer. A mutex still leaves me with the same question. – pnizzle Dec 19 '18 at 01:57
  • "dispatch work to thread B" - there is no way to dispatch work to a thread unless the thread is specially programmed to accept dispatched works. And threads do not return, they are not procedures. – Alexei Kaigorodov Dec 19 '18 at 06:19
  • A thread that is waiting on a code section protected by a mutex can absolutely be used for other tasks until that section is opened up, as my answer explains. A code section can be protected by a mutex without *holding* that mutex while it's running, as my answer explains. The mutex is only held during the tiny fraction of a second required to test or modify the *SHARED* stated, which is simply whether or not the code section is in use by another thread (a single yes/no value). – David Schwartz Dec 19 '18 at 09:24

2 Answers2

-1

You have a misunderstanding about how mutexes are typically used.

If you want to do some work, you acquire the mutex to figure out what work you need to do. You do this because "what work you need to do" is shared between the thread that decide what work needed to be done and the thread that's going to do the work. But then you release the mutex that protects "what work you need to do" while you do the work.

Then, when you finish the work, you acquire the mutex that protects your report that the work is done. This is needed because the status of the work is shared with other threads. You set that status to "done" and then you release the mutex.

Notice that no thread holds the mutex for very long, just for the microscopic fraction of a second it needs to check on or modify shared state. So to see if work is done, you can acquire the mutex that protects the reporting of the status of that work, check the status, and then release the mutex. The thread doing the work will not hold that mutex for longer than the tiny fraction of a second it needs to change that status.

If you're holding mutexes so long that you worry at all about waiting for them to be released, you're either doing something wrong or using mutexes in a very atypical way.

So use a mutex to protect the status of the work. If you need to wait for work to be done, also use a condition variable. Only hold that mutex while changing, or checking, the status of the work.

But, If a thread attempts to acquire an already acquired mutex, that thread will be forced to wait until the thread that originally acquired the mutex releases it. So, while that thread is waiting, can it actually be usable. This is where my question is.

If you consider any case where one thread might slow another thread down to be "waiting", then you can never avoid waiting. All that has to happen is one thread accesses memory and that might slow another thread down. So what do you do, never access memory?

When we talk about one thread "waiting" for another, what we mean is waiting for the thread to do actual work. We don't worry about the microscopic overhead of inter-thread synchronization both because there's nothing we can do about it and because it's negligible.

If you literally want to find some way that one thread can never, ever slow another thread down, you'll have to re-design pretty much everything we use threads for.

Update:

For example, consider some code that has a mutex and a boolean. The boolean indicates whether or not the work is done. The "assign work" flow looks like this:

  1. Create a work object with a mutex and a boolean. Set the boolean to false.
  2. Dispatch a thread to work on that object.

The "do work" flow looks like this:

  1. Do work. (The mutex is not held here.)
  2. Acquire mutex.
  3. Set boolean to true.
  4. Release mutex.

The "is work done" flow looks like this:

  1. Acquire mutex.
  2. Copy boolean.
  3. Release mutex.
  4. Look at copied value.

This allows one thread to do work and another thread to check if the work is done any time it wants to while doing other things. The only case where one thread waits for the other is the one-in-a-million case where a thread that needs to check if the work is done happens to check right at the instant that the work has just finished. Even in that case, it will typically block for less than a microsecond as the thread that holds the mutex only needs to set one boolean and release the mutex. And if even that bothers you, most mutexes have a non-blocking "try to lock" function (which you would use in the "check if work is done" flow so that the checking thread never blocks).

And this is the normal way mutexes are used. Actual contention is the exception, not the rule.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • But, If a thread attempts to acquire an already acquired mutex, that thread will be forced to wait until the thread that originally acquired the mutex releases it. So, while that thread is waiting, can it actually be usable. This is where my question is – pnizzle Dec 19 '18 at 01:56
  • I know you said then im 'doing something wrong' if a thread has to wait for a lengthy period of time. I did mentioned in my post that I know how to engineer my code for concurrency, and wouldn't have this situation. That is why it is hypothetical. Its simply for interests sake. Cheers – pnizzle Dec 19 '18 at 02:04
  • See updates to my answer. That's just not how threads work. When we say we don't want one thread to "wait" for another, we mean while the other thread does work that will take time. We don't worry about a microscopic chance of a microsecond wait, and I don't understand your question to be about that because it asks about doing something else, which only makes sense if you're talking about non-negligible amounts of time. You wouldn't even have enough time to start doing something else. – David Schwartz Dec 19 '18 at 04:04
  • Its all hypothetical. You might have missed that part. – pnizzle Dec 19 '18 at 04:18
  • And by waiting I'm talking about an indefinite amount, could be half a second. Could be 20 seconds. Could be an hour. And the bit that you are saying 'thats not how threads work', I have no idea what you mean mate. If a thread acquires an already acquired mutex it is forced to wait. It cant continue until that mutex is released by the thread that acquired it initially – pnizzle Dec 19 '18 at 04:22
  • 1
    I am now confident to say I think you don't know how mutexes work. Threads too It seems. You ignored the details in my question and rushed to suggest mutexes. Is that all you know (think you know) – pnizzle Dec 19 '18 at 04:23
  • `Is there a mechanism that does what im asking`. A mutex does not do it, simple, but who said mutex in the first place? I have no idea where you came from with this divergent answer mate – pnizzle Dec 19 '18 at 04:24
  • A mutex does exactly what you're asking. It allows one thread to check if another thread is finished doing work without having to wait for that other thread to finish doing work. – David Schwartz Dec 19 '18 at 09:22
  • Can you provide any proof of your word, David. My understanding of Mutexes could actually be flawed. I would be humbled to be proven wrong. I have failed to find any resources that support your claim. Could you provide something please? I will surely mark this as correct answer if it is. – pnizzle Dec 19 '18 at 09:26
  • I do threading on a daily. I use locks and semaphores all the time. I have used mutexes years back. I know when to use these. But to say that a thread waiting for a mutex to become relased can still be used or doesn’t really wait is false. This is what i need proof of from you. A link to supporting documentation would be good – pnizzle Dec 19 '18 at 09:36
  • That's not what I said. It seems like you're not reading my answer no matter how clear I try to make it. No thread waits for a mutex in the pseudo-code above except in a one-in-a-million coincidence case (that can only happen once and lasts less than a microsecond on modern hardware), and if even that bothers you, my answer explains how can even avoid that. – David Schwartz Dec 19 '18 at 09:37
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/185475/discussion-between-david-schwartz-and-pnizzle). – David Schwartz Dec 19 '18 at 09:40
-1

After much research, thought, and overview, I have come to the conclusion that its like asking:

If a calculator has the ability for me simply enter a series of 5 digits and automatically get their sum on the screen.

No, it does not have such a mode ready. But I can still get the sum with a few extra clicks using the plus and eventually the equal button.

If i really wanted a thread that can continue while listening for a condition of some sort, I could easily implement a personal class or object around the OS/kernel/SDK thread or whatever and make use of that.

• So at a low level, my answer is no, there is no such mechanism •

If a thread is waiting, then it's waiting. If it can continue executing then it is not really 'waiting', in the concurrency meaning of waiting. Otherwise there would be some other term for this state (Alert Waiting, anyone?). This is not to say it is not possible, just not with one simple low level predefined mechanism similar to a mutex or semaphore etc. One could wrap the required functionality in some class or object etc.

Having said that, there are Interrupts and Interrupt handlers, which come close to addressing this situation. However, an interrupt has to be defined, with its handler. The interrupts may actually be running on another thread (not to say a thread per interrupt). So a number of objects are involved here.

pnizzle
  • 6,243
  • 4
  • 52
  • 81