Thread syncro

Started by
15 comments, last by ProgramMax 21 years, 1 month ago
Could someone provide me with a decent example of a Critical Section in use and a Mutex object in use? When is it appropriate to use one and not the other? Thanks!
Advertisement
On Windows, a critical section is valid within a process and a mutex is valid across processes.

For details:

http://www.microsoft.com/msj/0198/Win320198.htm
http://spiderman.dyn.ee/papers/multithreading.html
http://www.devguy.com/fp/Tips/synchronization.htm
http://www.codeproject.com/threads/opbmutex.asp

google: win32 critical section mutex synchronization
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
Thanks. Actually just while waiting on the responce I found some good info and then did some thinking. I read earlier that critical sections are not shared across multiple processes. After my initial post, I read that critical sections are also faster than mutex objects.

So then I sat down and did some thinking. I have one thread that loads a queue with triangles and needs to tell the rendering thread when it is okay to start adding the triangles to the VB and IB. I also needed a good way to test when the rendering thread should shut down. Currently I have the code closing the thread right in the middle of the run. This could mean that in the middle of a DirectX call, the thread terminates. I don''t like the idea of that.

Anyway, here is my thinking (in terms of the termination critical section). I want to minimize the calls to Enter/LeaveCriticalSection() per frame. Instead of calling Enter and Leave every frame, and ending the loop when I couldn''t Enter, I wanted to find a better answer.

I came up with kinda a reverse-ownership critical section. If my rendering thread never gets ownership, it will never have to call LeaveCriticalSection(). So what I plan to do is have another thread own the critical section and have the rendering thread while( ! TryEnterCriticalSection() ). That way each frame never actually gets ownership. When I want the thread to end, it will gain ownership and will then Leave and close the thread.

Anyway, thanks for the links
Associate the CS with data, not with a thread. The point of a CS is to ensure that data access is restricted to one thread at a time.

I''m leary of wrapping TryEnterCriticalSection in a while statement like that. The advantage of TryEnterCriticalSection is that it never suspends a thread - putting it into a while loop like that appears to remove that advantage.
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
I understand that a CS is designed for sharing data between threads. However I needed some way to signal the end of the program so the other thread can close properly. Using a variable would get rid of the whole benefit of a CS, so I use a CS to mark the end of a thread.

As for the TryEnterCriticalSection(), I know that it is designed to avoid the block. Infact that''s exactly what I''m using it for. You see, now that I explained I need the CS to check for the end of the execution, I also now need a way to use that CS. The last thing I want is to add a block to my rendering thread. If I had a block in my rendering thread (other than rendering) I would kill myself. So anyway, my goal was to reduce the penalty of using a CS as much as possible. I figured I would use TryEnterCriticalSection() to avoid the block, but didn''t want to enter the critical section and then leave the critical section every frame. That would add even more overhead to each frame. So I figured if I could have a while loop that goes so long as TryEnterCriticalSection() fails, I wouldn''t have to enter/leave, and I would still have a signal to tell me wether or not I need to exit the thread.

So in a way, I took all the benefits of a CS and multithreading, but reversed the idea around a little bit so it would run faster.

The only real change I made was to inverse things. Instead of trying to have ownership of the CS, my rendering thread trys to NOT have ownership. As soon as it gains ownership, it knows it is time to close down the thread. That means my rendering thread now enters and leaves the CS only once, instead of once per frame. That is some hard-core improvement if you ask me.
quote:

... so I use a CS to mark the end of a thread....
... Instead of trying to have ownership of the CS, my rendering thread trys to NOT have ownership. As soon as it gains ownership, it knows it is time to close down the thread.



Hi there,

I know quite well what you are trying to archive since I also
went the same way. There is a much cleaner way, actually the way
it was designed to be

The handle returned by CreateThread, _beginthread, ... whatever
is actually an ''event''. So when you wait for your thread to exit,
just make a call to

WaitForSingleObject(hThread2Die,INFINITE);

in the Thread that has to wait. That''s it. Only after that
a call to CloseHandle will be safe. Your original method isn''t
safe, only an assumption that the thread might have ended. Killing it with ExitThread is another story.

Hope this is some help to you.

Lorenz
Just doublechecked.

Dunno whether this works also with _beginthread.
MSDN doesn''t say. You would have to try.

Bye




I know....I have that too. Here is a scenario:

say I have a thread, and the function the thread calls looks like this:

while( true )
{
// loop stuff
}

Given that scenario, the WaitForObject(blah, INFINITE) will never come...the loop always continues.

To remedy this I had to change that true to something else...I needed a way to find when the thread needed to exit. So I changed the loop to this:

while( ! TryEnterCriticalSection( blah ) )
{
// loop stuff
}
LeaveCriticalSection( blah );
return 0;

The main thread still calls WaitForSingleObject() and all to make it nice and clean...just it tells the thread that it is ready to shut down before it does that.

Give me a while and I will write a better description of the problem and my solution. I think it is pretty clever actually.
Okay, it''s write-up time. The first step in designing my code went into figuring out where each block is. A block is when the code stops execution and waits for something to happen. An example is GetMessage().

After I found my blocks, I started designing a way to keep each block in its own thread, and then have one extra worker thread. Anything more would be kinda wasteful.

An important note is to not try to avoid blocks. If I use PeekMessage() instead of GetMessage(), my program will take 99% of the CPU and will operate the same as it did anyway. Use blocks where you can.

After finding that I would have one block for the message pump and another block for rendering, I decided to put the rendering in a seperate thread. A thread will start up and run the thread''s function once. That means as soon as the function returns, the thread is ready to be closed. Obviously we want our rendering function to be called more than once. Infact it should loop until the engine is done.

So I put a while(true){...} in the thread. Now the rendering thread can be closed at any time, but that wouldn''t make for a clean and safe close. Especially because the thread is working with DX. Infact every now and then I was getting access violations when trying to close the thread. To combat that, I needed a way to exit the loop when it is time to close down the thread. I am looking for a way to while(active){...}, but I need to make it thread-safe and use as little CPU as possible. Remember, this is going to be called once each frame.

To fix the thread-safe issue, I created a critical section. I use the critical section as a boolean, true of false, wether the rendering thread had ownership or not. If the rendering thread could get ownership, it would continue rendering and then leave the critical section at the end of the rendering. This changed my loop to look like this: while( TryEnterCriticalSection(blah)){...LeaveCriticalSection(blah) }

I noticed that this meant I was now calling Leave each frame, plus am also Entering the Critical Section on each frame. I wanted to keep overhead as low as possible, and adding two system function calls isn''t going to help that. Then I realized that TryEnter will exit prematurely if it fails, if you can''t enter.

So long as another thread has ownership, TryEnter will fail and you won''t have to Leave. Plus you know the TryEnter exited prematurely and didn''t execute all of the function''s code, saving even a little bit of execution time in just that function. I decided to change my scheme then to that of a reverse Critical Section. Either way I just needed a bool to tell me if I should terminate.

While I want the rendering thread to run, I have the main thread keep ownership of the Critical Section. As soon as it is time to terminate the thread, the main thread gives up ownership. The rendering function now looks like this:
while( ! TryEnterCriticalSection( blah ) )
{
...
}
LeaveCriticalSection( blah )

That way the loop continues as needed, and you only actually enter and leave the CS once (when the thread exits).

The Reverse Critical Section aims at NOT having ownership, as opposed to the Critical Section that wants ownership.

Quick side notes: 1.) How do you put parts of a message into those code blocks? And, 2.) If this hasn''t been coined yet, I hereby claim the Reverse Critical Section as my own.
Just a question.

Why do you want to use that CS Stuff for your rendering loop ?
Why not just a simple bool like ''bStopRendering'' ?

If you want to stop the thread then just set it ''true''.
You can be sure that nothing will be faster than that.
After that cleaning up will be easy.

An example would be

void Thread
{
while(!bStopRendering)
{
// Render
}

DX_CLeanUP();
}

The calling thread will set that bool and make a call to
WaitForSingleObject right after and return when the threads allocated memory is released.

quote:
How do you put parts of a message into those code blocks?


What do you mean by ''parts'' ?

This topic is closed to new replies.

Advertisement