OK, I'm a bit confused here. The following code works:
HANDLE CreateSideThread()
{
DWORD dwGenericThread;
HANDLE hThread1 = CreateThread(NULL, 0, CallBackFunc, NULL, 0, &dwGenericThread);
return hThread1;
}
int main()
{
HANDLE Thread1;
Thread1 = CreateSideThread();
WaitForSingleObject(hThread1, INFINITE);
SomeOtherFunction();
return 0;
}
The program does other things but you get the idea. It basically creates a new thread and executes whatever it is in CallBackFunc (which is an endless loop that check db status).
Now, if I remove WaitForSingleObject() then the program will not even try CallBackFunc once and execute SomeOtherFunction().
What's the point then of a thread? I mean, i'm confused here.
What I am trying to do is call that thread with the check for the database status and keep that thread going while I continue with my program, calling other functions.
What am I doing wrong?
Please post a sample snippet.
Thanks
Without the WaitForSingleObject, your call to SomeOtherFunction() probably returns quickly enough for the program to exit before the new thread even gets a chance to run once.
When a C program returns from its main() function, the runtime system calls exit() for you. This forcibly exits your program even if other threads are trying to run at the same time. This is in contrast to other languages like Java for example, where exiting the main thread will not exit the process until all other (non-daemon) threads have finished running too.
Threads are typically used for doing background work and freeing up the calling thread to do other things.
Normally, the behavior you describe (calling SomeOtherFunction()) is exactly what you'd want: I am going to kick of a background 'job' and go about my life.
It would appear that your example is just fine - though if you merely return from main() your thread will of course terminate (as it's owned by the parent process).
Maybe some more detail on why what you're doing isn't what you expect to happen?
What you're finding is that the main thread completes before you notice CallbackFunc is called. When you have the Wait call in, the main thread is blocked until the new thread finishes and so you see the thread func being executed.
Threads are not as cheap as you think, if you replace the SomeOtherFunction with something that takes a long enough time to run, you'll see your thread function being called even without the Wait call.
CallBackFunc will of course be called, but there is no guarantee, when your stared threads will be up and running. They will be working once, but its unpredictable when the start doing so. Thats the job and property of the systems scheduler. In your case they do not anything when the second function is already called.
Related
i have a threadProc
void* ThreadProc(void* xyz)
{
//do some work..
}
now from the main thread.. i call this thread and do not wish to wait for it to finish
WaitForSingleObject(hThread, 0)
now my flow of program is succh that the case may arrive where
first call to thread is not finished and 2nd time same ThreadProc() is called.
So ...
1. How does OS handles this scenario? Will this kind of program give unexpected results?
2. If this is wrong way of doing it, what is the correct way?
Because ultimately I want one function to be called asynchronously, may be running multiple instances at the same time.
Every thread has a separate stack, so as long as all variables in the thread callback function are local, there are no conflicts. But if you would access variables that are global/static, then they are shared between all threads and all access to them needs to be handled carefully. Use mutex/semaphores/critical sections for such. The same goes for calling library functions which you don't know are thread-safe.
Will this kind of program give unexpected results?
That depends entirely on the body of the thread callback function. You should however wait using WaitForSingleObject(hThread, INFINITE). Right now you wait 0ms, which does nothing.
my main program (all c code) starts a server function as a separate thread (pthread_create).
This function waits for incoming input and does certain things with it. Meanwhile the main program keeps doing things as well (the main program does not wait for the server function to finish its job before it continues).
Now there is the chance that an error occurs in the server function (socket problem, ...). The server function then returns a certain value (for example "-1").
If that is the case I want to abort the execution of the whole program.
How can I handle this?
My only idea is to start a second thread that constantly verifies a global variable that the server thread changes in case of an error. Then the second thread handles the program abortion.
What other options do I have?
Kind regards
You can use pthread_join to wait for termination of the child thread in the parent thread.
Or pthread_cond_wait to implement a similar stuff.
I'm currently writing a program that the main thread is going to create three child threads. These threads are running simultaneously and what I want to do is once one of the child thread is done, I will check if the output is right. If it is, then terminate the other two threads; if not, then throw away this thread's result and wait for the other two threads' result.
I'm creating the three results in the main function with pthread_create. But I do not know how to use join function. If I use join function three times in the main function, it just waits one by one until the three threads are done.
My plan is like this:
int return_value;
main(){
pthread_create(&pid[0], NULL, fun0, NULL);
pthread_create(&pid[1], NULL, fun1, NULL);
pthread_create(&pid[2], NULL, fun2, NULL);
}
fun0(){
...
if( check the result is right ){
return_value = result;
if (pid[1] is running) pthread_kill( pid[1], SIGTERM );
if (pid[2] is running) pthread_kill( pid[2], SIGTERM );
}
fun1() ...
fun2() ...
function 0, 1, and 2 are similar to each other and once one function has the right answer, it will kill the other two threads. However, while running the program, once the pthread_kill is processed, the whole program is terminated, not just one thread. I don't know why.
And I still do not know if there are any other ways to code this program. Thanks for helping me out of this.
The pthread_kill() function is not designed to terminate threads, just like kill() is not designed to terminate processes. These functions just send signals, and their names are unfortunate byproducts of history. Certain signal handlers will cause the process to terminate. Using pthread_kill() allows you to select which thread handles a signal, but the signal handler will still do the exact same thing (e.g., terminate the process).
To terminate a thread, use pthread_cancel(). This will normally terminate the thread at the next cancellation point. Cancellation points are listed in the man page for pthread_cancel(), only certain functions like write(), sleep(), pthread_testcancel() are cancellation points.
However, if you set the cancelability type of the thread (with pthread_setcanceltype()) to PTHREAD_CANCEL_ASYNCHRONOUS, you can cancel the thread at any time. This can be DANGEROUS and you must be very careful. For example, if you cancel a thread in the middle of a malloc() call, you will get all sorts of nasty problems later on.
You will probably find it much easier to either test a shared variable every now and then, or perhaps even to use different processes which you can then just kill() if you don't need them any more. Canceling a thread is tricky.
Summary
Easiest option is to just test a variable in each thread to see if it should be canceled.
If this doesn't work, my next recommendation is to use fork() instead of pthread_create(), after which you can use kill().
If you want to play with fire, use asynchronous pthread_cancel(). This will probably explode in your face. You will have to spend hours of your precious time hunting bugs and trying to figure out how to do cleanup correctly. You will lose sleep and your cat will die from neglect.
I have a method which is is meant to write information into a struct. I want to make it run as a thread.
If I call it by itself, as childWriter((void*) &sa) it works.
If I call pthread_create(&writerChild, NULL, childWriter, (void*) &sa), it no longer works. It doesn't write to the shared object.
This is driving me mad. Why isn't it working, and how do I make it work?
What makes you so sure that the code doesn't execute? Note that if you do something like:
int main(int argc, char* argv[])
{
pthread_create(....);
return 0;
}
In the above, the program will quit right away, because the program exits as soon as the main thread has terminated. You need to "join" the thread (using pthread_join), in order to wait for the thread to have terminated. Note that spawning a thread and then joining it is actually worse than simply running the content that the thread would run (since spawning and then joining a thread is equivalent to running the content serially, plus it adds the overhead of the spawn/join). If you intend to multithread things, typically one spawns multiple threads and then either detaches them or joins them later.
Also, you should be cautious about sharing data between threads that can be modified; any object that is read from multiple threads and is modified in even one thread requires explicit locking around access to that object. Otherwise, you can end up with all sorts of garbage and corruption.
Short version:
Use pthread_join() before you read the data from the struct:
pthread_create(&writerChild, NULL, childWriter, (void*) &sa);
//if necessary, do some other tasks, not related to the struct, here
pthread_join(writerChild,NULL);
//now, you may read from the struct
If you are creating the thread in one function, & reading the struct in another function, simply shift the pthread_join statement to the latter, just before you read from the struct. (Also make sure that the pthread_t variable writerChild is visible in the reading function's scope)
Long version:
Threads are generally used in programs where tasks can be parallelized. I suppose your intention here is to read the data written to the struct after the childWriter function writes to it.
When you call your function in a single-threaded process, via:
childWriter((void*) &sa);
the thread / process shifts to execute the instructions that are part of your function. Only when the function returns, does the execution control return to the point from which you called the function. Hence, you can be sure that childWriter has completed its execution, before you begin to read from your struct in the calling function.
When you create a new thread, via:
pthread_create(&writerChild, NULL, childWriter, (void*) &sa);
the thread runs in parallel with your "main" thread. There is no guarantee that the newly created thread will get a chance to execute before the next instructions in the main thread get exectued, leave alone the possibilty that the childWriter thread function completes its execution prior to reading the struct.
Hence, you need to wait for the thread to complete its execution. This can be accomplished using pthread_join().
I am supposed to implement a userlevel threads library in C. To do so, I need to implement yield(), createThread() and destroyThread() functions. I believe I've got the basics right:
To keep track of threads, I'll use a queue of ThreadControlBlock elements (which resemble PCBs in an OS) that look like this:
struct ThreadControlBlock {
int ThreadId,
u_context *context };
We can use the setcontext() family of functions to "save" and "load" the context.
Upon initialization of the program, initialize ThreadQueue with no elements.
Now the part I am not getting: when a thread calls yield(), I get the current context and save it in a ThreadControlBlock and put in the queue. Then get the first element in the queue and load the context in it, and execution proceeds.
The question is, if I do this, say I am a thread calling yield() and the next thread is myself. If I am saving the context and loading it again, upon re-entering wouldn't I be at the exact same spot where I was (before calling yield()?) And this would keep going on forever?
When a thread calls yield(), you have to save the state of a thread that's about to return from a yield() call. Don't save the context from immediately before the yield().
The same issue actually applies if you're switching to another task, too - since that other task saved its context at the same point (where it was about to switch to a second task). Using setcontext() and getcontext(), you need to use a static variable to keep track of whether you're switching in or switching out:
static volatile int switched;
switched = 0;
getcontext(current->context);
if (!switched)
{
switched = 1;
setcontext(next->context);
}
Alternatively, you can just use swapcontext(current->context, next->context);
It's perfectly reasonable in your yield() implementation to check to see if the next thread is the current thread and treat that case as a no-op.
If there are no other threads to run besides the current thread then there is nothing else to do besides just return from yield. I wouldn't bother with calling swapcontext in this case, though -- just detect and return.
I think that what you are actually dealing with is what to do when no threads (including the current one) when yield is called. An easy way to deal with this is to have an idle thread, which is only run when the run queue (ready threads) is empty. This thread will probably just:
{
while (1) {
yield();
pause();
}
}
This allows your program to go to sleep (via pause) until a signal happens. Hopefully the signal will be some event that makes one of the other threads ready to run, so the next call to yield will run the other thread instead of running the idle thread again.