Sign in to follow this  

Thread Inter-Syncronization

This topic is 4248 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Ok, here is my problem: - A is a Socket Data Receiving Thread - B is processing Data, and Sending it out to a Client - A must signal B that data has arrived - B is allways alive, so geting some sort of signal from A is relatively simple using some sort of Mutex or something - Problem comes when 1) A must know that B has processed its data and 2) A cannot continue until B as processed its data. But I do not want to have A busy waiting for B, I would like to find a way to block the A thread, have a blocking wait, instead of a busy wait, where A sits in a loop asking "has B processed the data, can I continue?". Any ideas?

Share this post


Link to post
Share on other sites
Use a semaphore, or implement something like:


bool waitBool(bool evaluate)
{
while (!evaluate)
{
Thread::yield();
}
};


Where Thread::yield is a function that sleeps the current thread.

Share this post


Link to post
Share on other sites
Ok, but I don't want to have the thread suspended, because then, who would wake it up?

And I really didn't want to go into a sleep/check cycle, because that is too granular...

Blocking is pretty much what I'm looking for here...

Share this post


Link to post
Share on other sites
Hi,

Are you on a windows system? If you are, then I would recommend asynchronous I/O or I/O Completion ports... MSDN has good articles on them...

If you're not, have a look at the boost thread library.. they have some good synch objects... They have one that is really good that I used to help with the reader/writer problem that you are describing...

Share this post


Link to post
Share on other sites
Quote:
Original post by vetroXL
Hi,

Are you on a windows system? If you are, then I would recommend asynchronous I/O or I/O Completion ports... MSDN has good articles on them...

If you're not, have a look at the boost thread library.. they have some good synch objects... They have one that is really good that I used to help with the reader/writer problem that you are describing...


Thanks for the reply.

Yes, this is a Windows 2000/XP Project, and also for PDAs (WinCE). I really don't have the time nor the energy to go into boost for this, and any solution I find must work on both platforms...

@kuphryn: Could you please elaborate? Where would GDNet be without single-word replies...

Share this post


Link to post
Share on other sites
Ahh, well then Boost is out of the question if you're on a PDA system... I would recomend looking up Asynchrousouse I/O or I/O Completion ports.. you'll have to decide which one works best for you situation... but they both have built in notification schemes to help with synch issues...

I use I/O completion ports if I have to build a large scalable server... but Asycnh I/o is fine if you have less then 64 simultaneous clients (sp) or if you writting a client.

Share this post


Link to post
Share on other sites
Quote:
Original post by vetroXL
Ahh, well then Boost is out of the question if you're on a PDA system... I would recomend looking up Asynchrousouse I/O or I/O Completion ports.. you'll have to decide which one works best for you situation... but they both have built in notification schemes to help with synch issues...

I use I/O completion ports if I have to build a large scalable server... but Asycnh I/o is fine if you have less then 64 simultaneous clients (sp) or if you want a client.


Nope, not a solution either, I've already built a whole system around this design, so I'm not going to go in another direction at the first sight of trouble, eheh...

I just need a way to block A, and have B unblock A.

Share this post


Link to post
Share on other sites
Well, as you know I've just completed the threaded part of my resource loader, and it uses Boost::Condition for exactly what you want.

If you're not willing to use Boost for this, you can always see how they've implemented it. The Boost::Thread library seems pretty small, so it shouldn't be that hard.

Other than that, the term you need to search for is 'conditional variable'.

Share this post


Link to post
Share on other sites
wow! tough customer ;)

Have tried an event based system like this?

Lock( DWORD dwTimeWait = INFINITE )
{
WaitForSingleObject( m_hLock, dwTimeWait );
ResetEvent( m_hLock );
}

UnLock()
{
SetEvent( m_hLock );
}

Share this post


Link to post
Share on other sites
Why not use a conditional. A would wait on the condtional and B could then signal the conditional causing A to wake up.

Share this post


Link to post
Share on other sites
Quote:
Original post by vetroXL
wow! tough customer ;)

Have tried an event based system like this?

Lock( DWORD dwTimeWait = INFINITE )
{
WaitForSingleObject( m_hLock, dwTimeWait );
ResetEvent( m_hLock );
}

UnLock()
{
SetEvent( m_hLock );
}


Thanks VetroXL, I've worked with Threads and mutexes before, but I don't yet have experience with Events. Are Events used to signal other Threads? What API calls should I be looking at?

Rate++ [wink]

Share this post


Link to post
Share on other sites
Hi,

They are used for those purposes exactly, light weight signal objects...
CreateEvent is what is used above, they are Manual reset events, not Auto reset events... (btw I use that in production code on a distributed-parallel-warfare-simulaiton-system )

You can also use OpenEvent to open exsiting events...

THe semantics are the same as the mutuxes...

Tthanks for the Rate++

Share this post


Link to post
Share on other sites
You shouldn;t have A waiting on B at all. You should have A waiting on its socket and posting the data it reads to a work queue. B needs to be waiting on the work queue.

A would be structured like this.

loop forever
wait for data to appear on socket
read socket into buffer
grab queue mutex
enqueue data
signal queue-not-empty condition
ungrab queue mutex
end loop

B would be structured like this.

grab queue mutex
loop forever
wait on queue-not-empty condition
unqueue data
process data
end loop

Granted, you need to have an additional mutex guarding your queue so you can enqueue/unqueue multiple data packets without deadlock, but that's the idea. Each thread has one and only one loop invariant on which it will block while the invariant does not hold, and those invariants are different. Anything else is just inviting either deadlock or starvation.

Share this post


Link to post
Share on other sites
What Brigma is saying is what I/O completion ports are... with out all the queuieng code, windows does that for you

Share this post


Link to post
Share on other sites
Thanks Bregma, you've opened my eyes, I need to look at this from another angle.

Again, thanks for all the replies, Rating++.

Share this post


Link to post
Share on other sites
actually sounds more like a producer-consumer problem. i'd use a mutex to control access to shared data and multiple events to signal B has finished processing and B can process data. A can only continue when it has the mutex and B has finished processing (which is what I think you want).

A
-
1.) A (the producer) waits for the mutex.
2.) if the buffer is full or has enough data to be processed, then you release the mutex and wait until B has signaled the finished processing event.
3.) Repeat 1 and 2 until you have both the mutex and "B has finished processing" event.
4.) Produce more data.
5.) If there's enough data from B to consume, pulse a "B can process" event.

B
-
1.) B (the consumer) waits for the mutex.
2.) If there is nothing or not enough to consume, release the mutex and wait for the "B can process" event.
3.) Otherwise, if there is data to consume, process it, release the mutex, and pulse the "B has finished processing" event.

Share this post


Link to post
Share on other sites
I recommend you read this. It has loads of relevant examples. Whatever you do, avoid busy-waits and lock-step solutions.

Share this post


Link to post
Share on other sites

This topic is 4248 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this