Re: Mutex/Lock
On May 31, 4:21 am, Chris Forone <4...@gmx.at> wrote:
No, the first version is the one i need. its to suspend/resume in a well
defined position in code. So i had:
bool Resume()
bool Suspend()
bool Exit()
void Proc()
bool Exit()
{
mutex.Acquire();
if (active)
{
active = false, mutex.Release();
// wait for thread termination :-)))
}
mutex.Release();
}
ps: Ideas for better doing it are very welcome!
Chris,
It's funny I just implemented almost exactly the same thing. A thread
with Start, Stop, Suspend, and Resume, although in my case I implement
"Start" and "Resume" with the same function. I have been having good
results with this. I use two mutices; one for the thread handles
themselves, and another for the "suspend" flag. You may find this
unnecessary, but in my actual application the "suspend" flag mutex
protects many other things (it is a media playback application of
sorts that maintains a number of other timing related parameters as
well). Note that this isn't real C++:
====================
// threadmtx has default spin count of 0, suspendmtx set at 3000.
CRITICAL_SECTION threadmtx, suspendmtx;
HANDLE hthread = NULL;
bool paused = false;
bool quitflag = false;
Start () {
// Resume thread if it's suspended.
Lock suspendmtx;
paused = false;
Unlock suspendmtx;
// Start thread if it's not running.
Lock threadmtx;
if (hthread == NULL) {
quitflag = false;
hthread = CreateThread(..., Proc, ...);
}
Unlock threadmtx;
}
Suspend () {
// Pause thread.
Lock suspendmtx;
paused = true;
Unlock suspendmtx;
}
Stop () {
// stop thread if it's running
Lock threadmtx;
if (hthread != NULL) {
quitflag = true;
if (WaitForSingleObject(hthread, timeout) == WAIT_TIMEOUT)
TerminateThread(hthread); // sholdn't happen
CloseHandle(hthread);
hthread = NULL;
}
Unlock threadmtx;
}
Proc () {
bool ispaused = false, pausing, unpausing;
// loop until asked to quit
while (!quitflag) {
Lock suspendmtx;
pausing = paused && !ispaused;
unpausing = ispaused && !paused;
ispaused = paused;
Unlock suspendmtx;
if (pausing) {
// do anything you want to do when thread transitions to paused
} else if (unpausing) {
// do anything you want to do when thread transitions to
unpaused
}
if (paused) {
Sleep(10); // or whatever
continue;
}
do normal processing here;
}
}
==== END EXAMPLE ====
Again, apologies for the strange looking example, I pieced it together
in this email from a slightly more complex piece of code. The pausing/
unpausing logic isn't necessary for anything but it lets you do things
when the thread state changes, if you want, I thought I'd throw that
in there. Hopefully it makes sense.
In my case I made a slight trade-off of added code simplicity at the
expense of niceness. The "if (paused) { Sleep(10); continue; }" is the
culprit there. You may instead want to do something like "if (paused)
{ WaitForSingleObject(unpausedevent); }" and SetEvent(unpausedevent)
when you unpause the thread, that way it will sleep until you resume
it rather than looping and waiting.
You could also use SuspendThread/ResumeThread, depending on your
requirements. However, I am not sure where those functions actually
suspend the thread -- I don't know if Windows has a concept of
"suspend points" or if it just stops the thread right where it is in a
potentially unsafe place (for example, in the middle of a critical
section, or in the middle of sending data to an external hardware
device or whatever it is your thread does).
Jason