I am attempting to use SetEvent and WaitForMultipleObjects so I wrote a couple of functions that I wanted to synchronize using Events. I want the first function to execute, and then signal the second function to execute, which in turn signals the first function to execute again etc.
Two events were created, one initialized to a signaled state, the other unsignaled. The only way I can get the execution to flow as expected is when putting the each thread to sleep for 10 ms. I read about some caveats about using SetEvent:
http://cboard.cprogramming.com/windows-programming/100818-setevent-resetevent-3.html
My question is must I put my threads to sleep because these function calls require extra time to actually signal the events? When debugging sometimes an event that is set still remains unsignalled. I verify this using process explorer. My code basically looks like this:
in the main:
//1. FinCalcpidUpdatestruct << initialize to unsignalled
//2. FinUpdatestructCalcpid << initialize to signalled
FinCalcpidUpdatestruct = CreateEvent (NULL, FALSE, FALSE, TEXT("FinCalcpidUpdatestruct"));
FinUpdatestructCalcpid = CreateEvent (NULL, FALSE, TRUE, TEXT ("FinUpdatestructCalcpid"));
void function1()
{
int n;
int noGoCode;
n=0;
noGoCode = 0;
while(1)
{
//Sleep(10);
noGoCode = WaitForSingleObject (FinCalcpidUpdatestruct, INFINITE);
if (noGoCode == WAIT_OBJECT_0) {
//wait for FinCalcpidUpdatestruct to be signalled
BufferOut[n] = pid_data_array -> output;
//signal FinUpdatestructCalcpid
if(!SetEvent (FinUpdatestructCalcpid))
printf("Couldn't set the event FinUpdatestructCalcpid\n");
else{
printf("FinUpdatestructCalcpid event set\n");
Sleep(10);
}
}
else
printf("error\n");
}
}
void function2()
{
int nGoCode = 0;
while(1)
{
//wait for FinUpdatestructCalcpid to be signalled
// Sleep(10);
nGoCode = WaitForSingleObject (FinUpdatestructCalcpid, INFINITE);
if (nGoCode == WAIT_OBJECT_0) {
if(!SetEvent (FinCalcpidUpdatestruct))
printf("Couldn't set the event FinCalcpidUpdatestruct\n");
else{
printf("FinCalcpidUpdatestruct event set\n");
Sleep(10);
}
}
else
printf("error\n");
}//end while(1)
If the sleep is not used then sometimes the same function will run through the while loop a couple of times instead of ping ponging back and forth between the two functions. Any ideas?
You can fix the problem by adding a printf above the SetEvent call on each function.
The problem is that you are setting the event and then performing some output.
In function2 the printf occurs after the SetEvent:
// Add a printf call here to see sensible output.
if(!SetEvent (FinUpdatestructCalcpid))
printf("Couldn't set the event FinUpdatestructCalcpid\n");
else{
// Thread is pre-empted by kernel here. This is not executed immediately
printf("FinUpdatestructCalcpid event set\n");
}
The kernel preempts the thread running function2 so the FinUpdatestructCalcpid event has now been set, without the corresponding printf that you're expecting.
The thread running function1 is then executed and sets the FinUpdatestructCalcpid event. The thread running function2 is now allowed to execute and continues from where it left off. It runs the printf and because the FinUpdatestructCalcpid event has been set it immediately runs again.
The Sleep() calls you're using help to make this race condition unlikely, but do not eliminate it.
Let me cut your code short for brevity first:
FinCalcpidUpdatestruct = CreateEvent (NULL, FALSE, FALSE, TEXT("FinCalcpidUpdatestruct"));
FinUpdatestructCalcpid = CreateEvent (NULL, FALSE, TRUE, TEXT ("FinUpdatestructCalcpid"));
void function1()
{
while(1)
{
WaitForSingleObject (FinCalcpidUpdatestruct, INFINITE);
// Do Something
SetEvent (FinUpdatestructCalcpid);
printf(...);
Sleep(10);
}
}
void function2()
{
while(1)
{
nGoCode = WaitForSingleObject (FinUpdatestructCalcpid, INFINITE);
SetEvent (FinCalcpidUpdatestruct);
printf(...); // **A**
Sleep(10);
}
}
At basically any point of execution the control might be taken away from thread and given to another. Now suppose that function2 already set the event and is about to print output around **A** in code. Before the output is printed, the control is taken away and given to function1. The last printed output is already from function1 and its wait event is set, so it falls through and prints its stuff again.
When this happens, your output is once in a while:
function1
function2
function1
function2
function1
// When the situation **A** above happens:
function1
function2
function2
function1
// And we move on as usual further
function2
function1
function2
Set your events when you are done, that is after printf, and you will be fine.
Here's what I think...
You don't output any status until you have already set the event. At that point, execution could switch to the other thread before you output anything. If that thread runs first, then it might look as if one thread's loop has run through a second time -- a ping with out a pong...
But if you were to increment a global counter in between receiving a signal and setting an event, then save that counter's value to a local variable, you would probably find that one thread's count is always odd and the other's is always even (which is the behaviour you want), even if the output is not quite in order.
Related
What should i add to code to stop the signal and return to Main?
Do not use '() exit', i want to end or jump signal and go to main fuction.
i try to branch. but it's not works.
main{
void countdown(int);
signal (SIGALRM, countdown);
....
....
....
}
void countdown(int signum)
{
static int num =10;
printf("%d..",num--);
fflush(stdout);
if (num <0){
printf("DONE");
exit(0); // i want to change do not use exit() and get out this signal
}
}
You cannot invoke any of the functions you use from a signal handler. Only functions from man signal-safety list.
For the purpose of displaying progress indicator instead of using alarm/SIGALRM you may like start another thread that uses nanosleep to wait till the next tick and then print progress status.
signal invokes asynchronously a function when a call is received. When the called function (countdown here) terminates, it return right in the place left when the signal was caught.
So here, I'll say you just have to remove exit(0); and let the nature do the rest.
The perfect way to run and terminate threads in Windows using C is mentioned in the answer below!
There are 2 problems I'm facing with the current implementation method :
I can't forcibly stop the thread. For some reason it still continues. For example I have a for loop, it runs a function of which this thread example is a part. When this function is called 4-5 times, I see multiple animations on the screen suggesting that the previous threads didn't stop even when I called TerminateThread function at the end of my function.
At times the thread doesn't run at all and no animation is displayed on the screen. Which is if my function code runs really fast or for some other reason, I feel like the thread is being killed before it initializes. Is there a way to wait until init of thread?
How do I fix these issues?
Correct way of terminating threads is to signal the thread and let it finish gracefully, i.e.:
(updated to use interlocked intrinsics instead of a volatile flag, as per #IInspectable's comment below)
HANDLE eventHnd;
HANDLE threadHnd;
LONG isStopRequested = 0; // 1 = "stop requested"
static DWORD WINAPI thread_func(LPVOID lpParam)
{
do
{
// wait until signalled from a different thread
WaitForSingleObject(eventHnd, INFINITE);
// end thread if stop requested
if (InterlockedCompareExchange(&isStopRequested, 0, 0) == 1)
return 0;
// otherwise do some background work
Sleep(500);
} while (true);
}
The eventHnd variable is initialized using the CreateEvent function, and the stopRequested variable is just a boolean flag you can set from your main program:
// this creates an auto-reset event, initially set to 'false'
eventHnd = CreateEvent(NULL, false, false, NULL);
InterlockedExchange(&isStopRequested, 0);
threadHnd = CreateThread(NULL, 0, Processing_Thread, NULL, 0, NULL);
So, whenever you want to tell the thread do perform a task, you will simply set the event:
SetEvent(eventHnd);
And when you want to end the thread, you will set the flag to true, signal the event, and then wait for the thread to finish:
// request stop
InterlockedExchange(&isStopRequested, 1);
// signal the thread if it's waiting
SetEvent(eventHnd);
// wait until the thread terminates
WaitForSingleObject(threadHnd, 5000);
I want to implement a very simple design with pthreads:
From this image you only need to know that I have one thread that is created with start() and is destroyed with stop(), and inside the thread, there is a function that loops infinitely until stop() is called.
This what I have (mutexes are omitted):
int running = 0;
pthread_t thread;
void* fn (){
while (1){
if (!running) break;
if (foo ()){
//Error, how should I handle it?
//The main thread is still not waiting with join()
}
}
pthread_exit (0);
}
int start (){
running = 1;
if (pthread_create (&thread, 0, fn, 0)){
return -1;
}
return 0;
}
int stop (){
running = 0;
if (pthread_join (thread, 0)){
return -1;
}
return 0;
}
Usage:
start ();
//At this point the infinite loop is running
//Let's say that in the second 1 something fails inside the loop
//How can I handle the error if join() is still not called?
sleep (3);
stop ();
One solution to this problem is to use a callback. The error is passed to the main thread via a function passed as paramater to the secondary thread. The big problem with this is that I'm converting the program into an asynchronous model, which I'd like to avoid for now.
I can save the error in a global variable and check it when stop() is called. More solutions?
I am not really sure that I understand your problem correctly, but for pthread_join your thread must not necessarily be running anymore. It is perfectly legal to join a dead thread. The only constraint is that you can only call join once for any thread.
You should then transfer the information why your thread stop through the return argument of the thread function, that is what it is meant for, and your stop thread will receive that through the second parameter of join.
Also
your thread function has an incorrect interface, this leads to undefined behavior. modern ABIs transfer function arguments in registers, and here the two sides may have a different vision of which registers are safe to use
you only need pthread_exit when you return from another function than the thread function itself. a normal return would do.
Our current project is based on extending more by including scroll. In order to do this, a timer interval has to be set for a certain period. The part I'm not sure about is where the loop for the alarm signal should be. All the examples I've seen have the timer values in the main, then explicitly call the signal handler via pause() in an infinite while loop.
My code is a bit different, since the functionality requirements go like
print first screen of text after getting terminal dimensions
print prompt
if prompt = space, print another screen of text //WORKS
if prompe = q, restore original terminal settings & quit program //WORKS
if prompt = ENTER, initialize scroll at 1 line every 2 seconds //DOESN'T WORK
if prompt == f/s, increase/decrease scroll speed by 20% //DOESN'T WORK
The read in buffer, file pointer and itimerval struct are all global variables to avoid passing as arguments through a chain of functions.
The main function of the program is
void processInput(FILE *fp){
void printLine(int); //prints a single line of text
signal(SIGPROF, printLine);
int c;
//print first screen of text, check for more text to display
info(); //print prompt at bottom of screen
FILE *fterm= fopen("/dev/tty", "r");
while ((c=getc(fterm)) != EOF){
if (c== '\n'){
setTimer(2);
//four more conditionals like this in basic similarity
}
}
My setTimer function has a base interval of 2 seconds, and changes that by plus/minus 20% based on f/s input from the user.
void setTimer(int direction){
int speed=2000000; //2 seconds
int change= 400000; //400 milliseconds, 20% of 2 seconds
if (direction == 1) //slow down by 20%
speed+= change;
if (direction == 0)
speed -= change;
timer.it_value.tv_sec=2;
timer.it_value.tv_usec=0;
timer.it_interval.tv_sec=0;
timer.it_interval.tv_usec= speed;
setitimer(ITIMER_PROF, &timer, NULL);
}
First question: should I use SIGALRM vs SIGPROF, and alter the ITIMER_XXXX variable accordingly?
Second, where should I put in the loop to trigger the signal? I tried
while(1)
pause();
in several of the conditionals, but it had the effect of stopping the execution and ignoring any input.
Without knowing the details of your requirements, couldn't you do this more easily using
select()?
Set your initial select timeout to 2 seconds and adjust according to f/s input, meanwhile if there is any standard input before the timeout you process it.
More or less valid general outline:
int retval;
fd_set rfds;
int input = fileno(fterm);
struct timeval tv, delay;
delay.tv_sec = 2;
delay.tv_usec = 0;
while (true)
{
FD_ZERO(&rfds);
FD_SET(input, &rfds);
tv.tv_sec = delay.tv_sec;
tv.tv_usec = delay.tv_usec;
retval = select(input + 1, &rfds, NULL, NULL, &tv);
if (retval == -1)
perror("select()");
else
if (retval)
{
if (FD_ISSET(input, &rfds))
{
command = readInput(...);
switch(command)
{
case 'q' ... cleanup & quit
case 's' ... calc 20% off delay values
case etc ...
case default...error handling
}
}
}
else //timeout
printLine();
}
Working with pause() is dangerous because it's not an atomic operation ... your program could be interrupted by the OS causing you to "lose" the arrival of a signal. Additionally, when pause() itself returns because of the arrival of a signal, it will simply call pause() again. That means you're going to have to-do all your work inside of a signal handler, which may not be the best thing, i.e., if you're inside the signal handler when the next signal goes off, you can end up with some unpredictable behavior if you haven't planned for that sort of event.
A better approach would be to-do the following:
1) Setup a signal mask that blocks SIGPROF at the start of your program.
2) Rather than using a signal handler to-do your heavy lifting, use sigwait(), and set it up with a sigset_t that contains a mask for SIGPROF.
3) Setup the main flow of your program the following way:
sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset, SIGPROF);
sigprocmask(SIG_BLOCK, &sigset, NULL); //block the SIGPROF signal
//process your input
//if you need to, initialize your timer and set it to go off
while(SOME_FLAG_IS_TRUE) //maybe this loops forever ... depends on what you want?
{
sigwait(&sigset, &signal_num);
if (signal_num != SIGPROF)
continue;
//process input ...
//... setup new interval timer with correct timeout ...
//... repeat loop and/or exit loop or set flag to exit loop
}
That should always catch the signal from the interval timer since sigwait() will properly return after waiting for a signal to arrive to your process, and the SIGPROF signal is always blocked, meaning you can't "lose" signals ... instead at least one of them will be queued up and waiting for the next call to sigwait() to be detected just in case one arrives while you're processing something in your while-loop.
Hope this helps,
Jason
My application creates a thread and that runs in the background all the time. I can only terminate the thread manually, not from within the thread callback function.
At the moment I am using TerminateThread() to kill that thread but it's causing it to hang sometimes.
I know there is a way to use events and WaitForSingleObject() to make the thread terminate gracefully but I can't find an example about that.
Please, code is needed here.
TerminateThread is a bad idea, especially if your thread uses synchronization objects such as mutexes. It can lead to unreleased memory and handles, and to deadlocks, so you're correct that you need to do something else.
Typically, the way that a thread terminates is to return from the function that defines the thread. The main thread signals the worker thread to exit using an event object or a even a simple boolean if it's checked often enough. If the worker thread waits with WaitForSingleObject, you may need to change it to a WaitForMultipleObjects, where one of the objects is an event. The main thread would call SetEvent and the worker thread would wake up and return.
We really can't provide any useful code unless you show us what you're doing. Depending on what the worker thread is doing and how your main thread is communicating information to it, it could look very different.
Also, under [now very old] MSVC, you need to use _beginthreadex instead of CreateThread in order to avoid memory leaks in the CRT. See MSKB #104641.
Update:
One use of worker thread is as a "timer", to do some operation on regular intervals. At the most trivial:
for (;;) {
switch (WaitForSingleObject(kill_event, timeout)) {
case WAIT_TIMEOUT: /*do timer action*/ break;
default: return 0; /* exit the thread */
}
}
Another use is to do something on-demand. Basically the same, but with the timeout set to INFINITE and doing some action on WAIT_OBJECT_0 instead of WAIT_TIMEOUT. In this case you would need two events, one to make the thread wake up and do some action, another to make it wake up and quit:
HANDLE handles[2] = { action_handle, quit_handle };
for (;;) {
switch (WaitForMultipleObject(handles, 2, FALSE, INFINITE)) {
case WAIT_OBJECT_0 + 0: /* do action */ break;
default:
case WAIT_OBJECT_0 + 1: /* quit */ break;
}
}
Note that it's important that the loop do something reasonable if WFSO/WFMO return an error instead of one of the expected results. In both examples above, we simply treat an error as if we had been signaled to quit.
You could achieve the same result with the first example by closing the event handle from the main thread, causing the worker thread get an error from WaitForSingleObject and quit, but I wouldn't recommend that approach.
Since you don't know what the thread is doing, there is no way to safely terminate the thread from outside.
Why do you think you cannot terminate it from within?
You can create an event prior to starting the thread and pass that event's handle to the thread. You call SetEvent() on that event from the main thread to signal the thread to stop and then WaitForSingleObject on the thread handle to wait for the thread to actually have finished. Within the threads loop, you call WaitForSingleObject() on the event, specifying a timeout of 0 (zero), so that the call returns immediately even if the event is not set. If that call returns WAIT_TIMEOUT, the event is not set, if it returns WAIT_OBJECT_0, it is set. In the latter case you return from the thread function.
I presume your thread isn't just burning CPU cycles in an endless loop, but does some waiting, maybe through calling Sleep(). If so, you can do the sleeping in WaitForSingleObject instead, by passing a timeout to it.
What are you doing in the background thread? If you're looping over something, you can end the thread within itself by having a shared public static object (like a Boolean) that you set to true from the foreground thread and that the background thread checks for and exits cleanly when set to true.
It is a code example for thread management in the fork-join manner. It use struct Thread as a thread descriptor.
Let's introduce some abstraction of the thread descriptor data structure:
#include <Windows.h>
struct Thread
{
volatile BOOL stop;
HANDLE event;
HANDLE thread;
};
typedef DWORD ( __stdcall *START_ROUTINE)(struct Thread* self, LPVOID lpThreadParameter);
struct BootstrapArg
{
LPVOID arg;
START_ROUTINE body;
struct Thread* self;
};
Functions for the thread parent use:
StartThread() initialize this structure and launches new thread.
StopThread() initiate thread termination and wait until thread will be actually terminated.
DWORD __stdcall ThreadBootstrap(LPVOID lpThreadParameter)
{
struct BootstrapArg ba = *(struct BootstrapArg*)lpThreadParameter;
free(lpThreadParameter);
return ba.body(ba.self, ba.arg);
}
VOID StartThread(struct Thread* CONST thread, START_ROUTINE body, LPVOID arg)
{
thread->event = CreateEvent(NULL, TRUE, FALSE, NULL);
thread->stop = FALSE;
thread->thread = NULL;
if ((thread->event != NULL) && (thread->event != INVALID_HANDLE_VALUE))
{
struct BootstrapArg* ba = (struct BootstrapArg*)malloc(sizeof(struct BootstrapArg));
ba->arg = arg;
ba->body = body;
ba->self = thread;
thread->thread = CreateThread(NULL, 0, ThreadBootstrap, ba, 0, NULL);
if ((thread->thread == NULL) || (thread->thread == INVALID_HANDLE_VALUE))
{
free(ba);
}
}
}
DWORD StopThread(struct Thread* CONST thread)
{
DWORD status = ERROR_INVALID_PARAMETER;
thread->stop = TRUE;
SetEvent(thread->event);
WaitForSingleObject(thread->thread, INFINITE);
GetExitCodeThread(thread->thread, &status);
CloseHandle(thread->event);
CloseHandle(thread->thread);
thread->event = NULL;
thread->thread = NULL;
return status;
}
This set of functions is expected to be used from the thread launched by StartThread():
IsThreadStopped() - Check for the termination request. Must be used after waiting on the below functions to identify the actual reason of the termination of waiting state.
ThreadSleep() - Replaces use of Sleep() for intra-thread code.
ThreadWaitForSingleObject() - Replaces use of WaitForSingleObject() for intra-thread code.
ThreadWaitForMultipleObjects() - Replaces use of WaitForMultipleObjects() for intra-thread code.
First function can be used for light-weight checks for termination request during long-running job processing. (For example big file compression).
Rest of the functions handle the case of waiting for some system resources, like events, semaphores etc. (For example worker thread waiting new request arriving from the requests queue).
BOOL IsThreadStopped(struct Thread* CONST thread)
{
return thread->stop;
}
VOID ThreadSleep(struct Thread* CONST thread, DWORD dwMilliseconds)
{
WaitForSingleObject(thread->event, dwMilliseconds);
}
DWORD ThreadWaitForSingleObject(struct Thread* CONST thread, HANDLE hHandle, DWORD dwMilliseconds)
{
HANDLE handles[2] = {hHandle, thread->event};
return WaitForMultipleObjects(2, handles, FALSE, dwMilliseconds);
}
DWORD ThreadWaitForMultipleObjects(struct Thread* CONST thread, DWORD nCount, CONST HANDLE* lpHandles, DWORD dwMilliseconds)
{
HANDLE* handles = (HANDLE*)malloc(sizeof(HANDLE) * (nCount + 1U));
DWORD status;
memcpy(handles, lpHandles, nCount * sizeof(HANDLE));
handles[nCount] = thread->event;
status = WaitForMultipleObjects(2, handles, FALSE, dwMilliseconds);
free(handles);
return status;
}