i've been trying and searching to fix a problem in my program for several hours, and i haven't found any solution. My problem is the following: i have a program receiving queries to be executed, this program can take the queries as redirection or by input. When it's by input, the program needs to stop when user do CTRL+C or CTRL+D, before quitting the program, it needs to save the database. So i used fgets for reading queries to do something like:
void* queries_(void* prm){
while(fgets(buffer, 64, stdin)){..}
}
I used threads to speed up queries processing when we pass a file to the program by redirection. This is when i got a problem. I added threads to the main function calling this queries_processing function like this.
int main(int argc, char const *argv[]) {
signal(SIGINT, stop_);
pthread_create(&thread1, NULL, queries_, &db);
pthread_create(&thread2, NULL, queries_, &db);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
// save database ...
}
But this is the part that i didn't understand, when user do CTRL+D, the while loop in queries_ stops for both threads and we get back to the main function and execute what is after the pthread_join. And for the ctrl+C, i created a function handler called stop_ where i fclose(stdin) to stop the while loop. But when i call this handler, the program get stuck, nothing happens, and the insturctions after the pthread_join isn't executed.
Any ideas what's causing that?
Do not call fgetc/fgets/fscanf on the same file handle (in this cases stdin) from multiple threads at the same time. Your program behavior is unspecified due to an unremovable race condition in the kernel.
Try using one thread to read from stdin and passing the line it read to the next available worker thread.
Related
I'm making a program where I have multiple threads working at the same time. After messing with the code for a while, I had an issue where I would send a string (char *) to the thread to do further operations with, and somehow the string did not send at all.
Later, I wrote a very simple code where I just send a string to a thread and the function prints it to the console. I found out that without using pthread_join(), it wouldn't work at all. I have no idea why, because I know that whenever pthread_join() is called, it blocks every other thread and waits until that one is finished.
Here's the simple program:
void* prisntstr(void* string);
int main(int argc, char *argv[])
{
char* string = "Hello!";
pthread_t thread;
pthread_create(&thread, NULL, prisntstr, (void*)string);
pthread_join(thread, NULL);
}
void* prisntstr(void* string)
{
char* str = (char*)string;
printf("%s\n", str);
}
Does anyone know how I can do this without using pthread_join()?
The problem with your program, if you remove the pthread_join, is that main is returning and thereby causing the program to exit without doing anything to synchronize with the other thread and determine whether it's actually finished. When main returns, it's just as if you called exit, and the whole process terminates.
Aside from pthread_join there are lots of ways you could make main wait for other actions to be finished. You could wait on a semaphore that the other threads post, you could loop on a condition variable inspecting data other threads set, etc.
Alternatively you could have main call pthread_exit so to terminate the initial thread. Then the process will not exit until you call exit or until each thread has exited.
The thread calling pthread_join() just waits for another thread to finish. Please note that:
If that thread has already terminated, then pthread_join() returns immediately
It is the most elegant way for doing it, being the others more complicated, and involving IPC tecniques:
the calling thread could wait for a mutex/semaphore put by the secondary thread
the calling thread could wait for a signal sent by the secondary thread
... and so on
So basically the strategy is: synchronize threads so that
The main thread can obtain some information calculated by the child thread
The process is kept alive until the child thread has completed its action (like in this case)
The reason why without pthread_join() you dont see that message printed to stdout is that as soon as main terminate, it terminates the whole process and all children threads are terminated; in your case before the print is executed.
When you use thread in your program, created thread will became child thread and the main program will became main thread. So, we need to block the main thread so that it can not close.
If main thread closed then child threads will be exit as well.
So, You need to find the way how to block main thread to not exit.
thread gives us the facility for that is pthread_join(). This will block the main thread until the child thread is working. Main thread will block on pthread_join() line. It will not execute other lines.
If you want to not use pthread_join() you need to find other ways for that.
Ex:
while(1);
while(1); will not end the main thread until you kill the process.
I'm very new to threads, processes, execv, etc. I have researched and found that when you execute an execv, it takes the space of the calling process. I am wondering what happens when you create a thread in main, and then call execv, directly after the thread (not before it finishes but right after the thread is created). I know execv will replace main but does this mean that it will also replace the thread or will the thread be able to execute and complete like normal?
Small example of what I'm asking:
int main(){
printf("hello from main!);
char *buffer = "some data";
if(pthread_creat(&mythreadpid, NULL, thread1, buffer){
printf("ERROR!!");
}
execv(...) //do execv here
}
void *thread1(void *buffer){
printf("calling from my thread!");
//do something else
}
I have tested this and I did experience strange behavior as my thread wouldn't complete so I want to know if this is the reason for it
All the exec functions replace the entire process with the program being executed. All threads are destroyed.
If you want to execute another program without affecting the current process, you should use fork() first to create a new process, and call execv() in the child process. See Is it safe to fork from within a thread? for some caveats to be aware of when using fork() in a multi-threaded program.
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 socket programming problem. I am running the server and then it waits for the client. Once I run the client though, nothing happens, it just terminates and brings back the prompt. Basically it compiles alright but it doesn't run at all. It terminates as soon as I run it. This only happens when I use threads in the client code.
This is the code I'm using:
if(pthread_create(&threadID[i++], NULL, (void *)dostuff, (void *)(intptr_t)sock) != 0)
{
perror("Thread create error");
}
On the other hand, if I type in simply
dostuff(sock);
The client program does execute. I need threading because I need to implement I/O multiplexing. Could you tell me how to stop the client from terminating when I use threads?
You'll need to wait for the thread to finish before exiting the program, for example using pthread_join
// do this before returning from main
pthread_join(threadID[i], NULL);
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.