C ++ atomic operation

In the C ++ Windows platform, I want to execute a set of function calls as atomic so that the execution does not switch to other threads of my process. How should I do it? Any ideas, tips?

EDIT: I have a piece of code, for example:

someObject->Restart(); WaitForSingleObject(handle, INFINITE); 

Now the Restart () function does its work asynchronously, so it returns quickly, and when this someObject is restarted, it sends me an event from another thread, where I signal the event descriptor on which I am waiting and, therefore, continue processing. But now the problem is that before the code reaches the WaitForSingleObject () part , I get a restart completion event, and I signal this event, and then WaitForSingleObject () never returns, since it is not signaled again. So I want to execute both Restart () and WaitForSingleObject () as atomic.

+4
source share
7 answers

This is generally impossible. You cannot force the OS not to switch to other threads.
What you can do is one of the following:

  • Use locks, mutexes, critical sections, or semaphores to synchronize multiple threads that relate to the same data.
  • Use basic operations that are atomic, such as compare-and-exchange or atomic-add as win32 api calls, such as InterlockedIncrement() and InterlockedCompareExchange()
+9
source

You do not want all the threads to wait, you just want to wait for the completion of the new thread without risking losing the signal. This can be done using a semaphore.

Create a semaphore known both for this code and a code that is ultimately executed by rebooting using CreateSemaphore (NULL, 0,1, NULL). In the code you specified, you will still use WaitforSingleObject to wait for your semaphore. When the thread executing the Release code executes with its work, ask it to call ReleaseSemaphore.

If ReleaseSemaphore is called first, WaitforSingleObject will let you pass immediately. If WaitforSingleObject is called first, it will wait for ReleaseSemaphore.

MSDN should also help you.

+7
source

The general solution to a lost race of events is a counting semaphore.

+2
source

Do you PulseEvent() to signal? If so, then the problem.

According to MSDN ,

If the threads do not expect or not the thread can be immediately released, PulseEvent simply sets the event state of the object to an inconsistent one and returns.

Therefore, if the handle is signaled before you wait for it, the handle will be placed immediately in an unsigned state on PulseEvent() . This seems to be why you missed the event. To fix this, replace PulseEvent() with SetEvent() .

In such a scenario, you may need to reset the event after the wait completes. This, of course, depends on whether this code is executed more than once during the life of your application. Assuming your pending thread is the only thread that the handle expects, use CreateEvent() to CreateEvent() auto reset event. This will automatically be reset by the descriptor after your waiting thread is released, which will make it automatically available the next time.

+1
source

Well, you can pause (using SuspendThread ) all other threads in this process, but I assume that you should rethink the design of your program.

0
source

This is very easy to fix. Just make sure the event is an auto-reset event (see CreateEvent Parameters) and just call SetEvent on the event descriptor, never call ResetEvent or PulseEvent or some other things. That way, WaitForSingleObject will always return properly. If the event is already set, WaitForSingleObject will immediately return and reset the event.

0
source

Although I am worried about your design as a whole (that is, you make parallel tasks consistent, thereby losing all the benefits of hard work to make it simultaneous), I think I see a simple solution.

Change the event descriptor as MANUAL RESET instead of AUTORESET. (see CreateEvent).

Then you will not miss a signal. After WaitForSingleObject (...) call the ResetEvent () function.

EDIT: Forget what I just said. This will not work. see comments below.

-one
source

All Articles