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().
Related
I'm writing code to save text to a binary file, which includes a function to auto-save text to the binary file, as well as a function to print from the binary file, and I need to incorporate pthread locks and join. We were given
pthread_mutext_t mutex;
pthread_t autosavethread;
as global variables, although the instructor didn't talk about what pthread or mutex actually do, so I'm confused about that.
Also, I understand that I need to use locks whenever shared variables are changed or read (in my case it would be the binary file). But at the end of the file I am supposed to use pthread_join, and I don't know what it does or what arguments are supposed to be used in it. I'm guessing mutex and autosavethread are supposed to be closed, or something along the lines of that, but I don't know how to write it. Can anyone help better my understanding?
There are two types of pthread - joinable thread & detached thread.
If you want to let a thread just take a task and go away once the task is done, you need the detached thread;
If you want to have the communication with the created thread when that thread is done with the assigned job, you have to use joinable thread. Basically it's needed when the parent & its created thread need to communicate after the thread is done.
It's very to google what exactly you need to call the pthread APIs and what can be communicated.
But one thing i want to mention here is, for the joinable thread, you have to explicitly call the pthread_join against the created thread. Otherwise, there will be serious memory leaks. When the joinable thread completes its task, the thread seems to exit (On linux, you can check the /proc/PID/task/ folder and once the thread completes, the entry under it will go away), but the resource allocated for this joinable thread, i.e. stack, is still there in the process memory space. As more and more joinable threads created and completing their tasks, the stacks for each thread are just left in process space, unless you explicitly call the pthread_join. Hope that helps, even a bit
The first argument of pthread_create() is a thread object which is used to identify the newly-created thread. However, I'm not sure I completely understand the implacations of this.
For instance, I am writing a simple chat server and I plan on using threads. Threads will be coming and going at all times, so keeping track of thread objects could be complicated. However, I don't think I should need to identify individual threads. Could I simply use the same thread object for the first argument of pthread_create() over and over again, or are there other ramifications for this?
If you throw away the thread identifiers by overwriting the same variable with the ID of each thread you create, you'll not be able to use pthread_join() to collect the exit status of threads. So, you may as well make the threads detached (non-joinable) when you call pthread_create().
If you don't make the threads detached, exiting threads will continue to use some resource, so continually creating attached (non-detached) threads that exit will use up system resources — a memory leak.
Read the manual at http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_create.html
According to it:
"Upon successful completion, pthread_create() shall store the ID of the created thread in the location referenced by thread."
I think pthread_create just overwrites the value in the first argument. It does not read it, doesn't care what is inside it. So you can get a new thread from pthread_create, but you can't make it reuse an existing thread. If you would like to reuse your threads, that is more complicated.
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.
Is it possible for two threads to use a single function "ThreadProc" as its thread procedure when CreateThread() is used?
HANDLE thread1= CreateThread( NULL, //Choose default security
0, //Default stack size
(LPTHREAD_START_ROUTINE)&ThreadProc,
//Routine to execute. I want this routine to be different each time as I want each thread to perform a different functionality.
(LPVOID) &i, //Thread parameter
0, //Immediately run the thread
&dwThreadId //Thread Id
)
HANDLE thread2= CreateThread( NULL, //Choose default security
0, //Default stack size
(LPTHREAD_START_ROUTINE)&ThreadProc,
//Routine to execute. I want this routine to be different each time as I want each thread to perform a different functionality.
(LPVOID) &i, //Thread parameter
0, //Immediately run the thread
&dwThreadId //Thread Id
)
Would the above code create two threads each with same functionality(since thread procedure for both of the threads is same.) Am I doing it correctly?
If it is possible then would there be any synchronization issues since both threads are using same Thread Procedure.
Please help me with this. I am really confused and could not find anything over the internet.
It is fine to use the same function as a thread entry point for multiple threads.
However, from the posted code the address of i is being passed to both threads. If either thread modifies this memory and the other reads then there is a race condition on i. Without seeing the declaration of i it is probably a local variable. This is dangerous as the threads require that i exist for their lifetime. If i does not the threads will have a dangling pointer. It is common practice to dynamically allocate thread arguments and have each thread free its arguments.
Yes, it is very well possible to have multiple (concurrent) threads that start with the same entry point.
Apart from the fact that the OS/threading library specifies the signature and calls it, there is nothing special about a thread entry point function. It can be used to start off multiple threads with the same caveats as for calling any other function from multiple threads: you need synchronization to access non-atomic shared variables.
Each thread uses its own stack area, but that gets allocated by the OS before the Thread Procedure get invoked, so by the time the Thread Procedure gets called all the special actions that are needed to create and start a new thread have already taken place.
Whether the threads are using the same code or not is irrelevant. It has no effect whatsoever on synchronization. It behaves precisely the same as if they were different functions. The issues with potential races is the same.
You probably don't want to pass both threads the same pointers. That will likely lead to data races. (Though we'd have to see the code to know for sure.)
Your code is right. There is NOT any synchronization issues between both threads. If they need synchronization, it maybe because they are change the same global variable, not because they use the same thread Procedure.
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.