Logic in concurrent threads

real_icecoke
real_icecoke used Ask the Experts™
on
Hi there,

I have a logical problem where I'm just not sure how to solve this programmatically.
Let's assume this situation:

I have e.g. 4 Threads running - doing all the (nearly) same stuff which depends on external processes (hardware in this case) - let us name these threads "A-Threads". And on the other hands, I have 1 to 20 (or more) other threads waiting for the results from one the first A-Threads (each of these second threads hands over some work to a particular A-Thread) - let us name these 'B-Threads'.

I could solve this easily with critical sections when I just have just 1 A-Thread. And I maybe can handle this with WaitForMultipleObjects when I have more than one A-Thread - sending a message out that THIS A-Thread has finished its work and has 'time' to do the next work for a B-Thread - BUT - and here comes my question on this:

I just want ONE of my B-Threads to take over the A-Thread that finished its work to do some more for this particular B-Thread. How can I do this? I mean, how can I get sure that just ONE B-Thread takes over an A-Thread to let him work?
Is this possible and how would I get sure that there is no B-Thread that is waiting infinite to get his hands on an A-Thread? Because each time a B-Thread dies, another B-Thread fires up and will wait for an free A-Thread.

Any help and code snippets are welcome!

Many thanks in advance!

icecoke
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Senior Developer
Commented:
maybe you could do a PostThreadMessage to the particular thread you want

Author

Commented:
loki,

thanks for the idea, but that is part of my problem - I dunno at designtime which thread may wait for some of the others.

I thought about doing a list that is holding all possible 'A-Threads' that are free for work - protecting the list with a simple critical section.. But that allways leeds me to the need for something like a 'n-channel-critical-section' where 'n' is determined at runtime to respect the amount of A-Threads.

....thinking....
...some coke....

hmmm, what about using the PostThreadMessage in something like a queue:

### B-Thread:
entercritsec
add own thread ID into a global list
leavecritsec
do a while loop until we peek a message with the A-thread ID which is free for us
start work with the other tread

### A-Thread:
each time we ended our work:
entercritsec
pull first B-thread ID from the global list
leavecritsec
PostThreadMessage to particular B-Thread that we are free for work


Do I miss something? I mean, both threads need to have something like a timeout if the
opponent Thread died or something, but is there something obvious that I miss?

icecoke
TheRealLokiSenior Developer

Commented:
are you able to paste some of your code for both the a and b threads, replacing the "waiting on hardware" with just a sleep(10000) or similar, so we can get a handle on this. You seem to have lost me :-)
If not, can you explain the real life issue more
eg. is it something like

I have delivery men (A threads) waiting for donuts to be made (external device/hardware)
When the donuts are made, the delivery man (A) takes them and delivers them
I have several Homers (B Threads) watching for delivery men (A threads) to go by.
When a Homer (B Thread) sees a delivery man (A Thread) has come by, he flags him down, eats his donuts and sends him back to the donut shop
(is it the same donut shop?)
I want to make sure that all the homers get a chance, and we dont end up with skinny homers, or 1 too fat homer.

-or is it more like :-

I have delivery men (A threads) waiting for donuts to be made (external device/hardware)
When the donuts are made, the delivery man (A) takes them and delivers them
I have one Homer (B Thread) waiting for a delivery men (A threads) to go by.
When this Homer (B Thread) sees a delivery man (A Thread) has come by, he calls for another Homer to stand on the kerb,
flags down the delivery man, eats his donuts and sends him back to the donut shop
(is it the same donut shop?)
A new homer is created every time, but they are not reused ?

hope this hasn't just confused everyone else :-)
Exploring SQL Server 2016: Fundamentals

Learn the fundamentals of Microsoft SQL Server, a relational database management system that stores and retrieves data when requested by other software applications.

Author

Commented:
LOL - these two storys are worth the 500 points - hehe. Ok, I have to think about this a second to build my own "story" that matches the situation. I have no sample code atm that shows the n to m situation as in the current application there is just a 1 to n situation done with critical sections.

But - thinking about donut shops I have this situation here:

In my street I have 4 (n) donut shops (A-Threads), all making just ONE fresh donut (yum) at the time. In this street several (m) Homers (B-Threads) come by to get only ONE (yes unbelievable for a Homer, but it is that way) donut. After he got one, he leaves the street and comes never again. But you can be sure a different Homer will come and he wants also ONE fresh donut. And: the donut shops (A-Threads) will ONLY make a fresh donut when a Homer (B-Thread) is asking for it. Otherwise the donut shop will idle....

The code must work with different numbers of shops and waiting homers. Sometimes we have no homers in the street and sometimes there are many homers. This is all decided at runtime by the user - where the number of shops is set at the beginning of the application (depending on the connected hardware) and the number of Homers depends on the workflow.

I hope we are not completely lost after three homer storys ;)
TheRealLokiSenior Developer

Commented:
Is the "donut" a static object that can be passed from the A thread (donut shop) to the B thread (Homer)
or must homer continue to use the donut shop (eg. haggle price of said donut, beghin eating donut, wipe crumbs on shop assistant)

What I'm trying to work out is if homer gets 1 quick donut and goes away to work on it himself, or whether he needs to work on it with the donut shop for a while, not just a simple passing of 1 data element

Author

Commented:
To behonest, the B thread (homer) brings everything in to the A thread (donut shop) so that the A thread does the work on it, while homer waits, and after the shop hands the donut out, homer leaves the street :)

So what you might want to know is that there is some (variable) input from the B thread to the A thread, the A thread works with this data while the B thread must idle, after the A thread is finished, it gives some output back to the B thread and both threads never see them again while this application runs (cause B thread will terminate after some further work with the output from A thread).



Tomas Helgi JohannssonDatabase Administrator / Software Engineer

Commented:
   Hi!

I would suggest to use 2 Queues in this problem.
Thread A monitor one queue (Qa) and thread B the other (Qb).
When A has finished process some data it puts it on Qb for thread B to take over and
process it. Then after thread B finishises the dataprocessing it puts the results into Qa
for Thread A to manage the data.
When no data is in the queues the threads become idle until some data is put on the queues.
Just make sure that the Queues are thread safe.

Regards,
   Tomas Helgi

Author

Commented:
Why two queues? I see no reason for this.
Atm I have one queue in my chart - a simple stringlist, protected with one cirtsec. Each time a homer comes into the street, it puts his name intot he queue and idles. When a donut shop is free for work it opens the queue and pulls a homer name out of it (assure FIFO). Then the appropriate Homer gets a PostThreadMessage and he can handle out the flour and sugar to the donut shop. The shop is doing its work and gives back the donut to the homer (its a special donut because flour and sugar was special). Now the Homer leaves and and the shop can have a look for the next name in the queue (like all other shops in the street do).

This gives me the ability to handle as much 'shops' as the user connects to the application at runtime and as much homers as there might come up in the street (load of the application).

A second queue wouldn't assure that the right homer gets the right donut.

Ok, so I guess the most important thing here was the PostThreadMessage thing I forgot to think of and the cool homer/donut story of Loki. So - thanks to Loki (and of course to Tomas).

gracias,
icecoke
TheRealLokiSenior Developer

Commented:
lol, thanks :-)

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial