Having this piece of code:
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
void* PrintHello(void* data){
printf("Hello from new thread\n");
pthread_exit(NULL);
}
int main(int argc, char* argv[]){
int rc;
pthread_t thread_id;
T_DATA data;
Data = init_data();
rc = pthread_create(&thread_id, NULL, PrintHello, (void*)data);
if(rc){
printf("\n ERROR: return code from pthread_create is %d \n", rc);
exit(1);
}
sleep(100);
printf("\n Created new thread (%d) ... \n", thread_id);
pthread_join(thread_id);
}
When main creates the new thread and then perform sleep(100), the new thread probably reach pthread_exit before main reach pthread_join. Anyways the new thread waits and his resources are not freed until main perform pthread_join so if i execute ps command i will see the new thread during next 100 seconds, am i right?. I would get the same behavior if I use pthread_detach instead pthread_join? I wonder what happen when the new thread perform the pthread_exit before main perform pthread_detach over the thread.
The thread cannot be cleaned up until it terminates, of course. But it also cannot be cleaned up until it is either joined or detached. A thread that terminates without being detached will keep enough information around to allow another thread to join it.
Related
When we detach a thread, it is not associated with calling thread anymore then why did the join call succeed with return value 0??
// C program to show thread functions
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
void* func(void* arg)
{
int x = pthread_detach(pthread_self());
printf("x = %d\n", x);
printf("Error description is : %s\n",strerror(x));
printf("Inside the thread\n");
pthread_exit(NULL);
}
void fun()
{
pthread_t ptid;
pthread_create(&ptid, NULL, &func, NULL);
int x = pthread_join(ptid, NULL);
printf("Error description is : %s\n",strerror(x));
pthread_exit(NULL);
}
int main()
{
fun();
return 0;
}
Output -
x = 0
Error description is : Success
Inside the thread
Error description is : Success
as you can see from above code, pthread_join returned success on an already detached thread.
I can reproduce the behavior you describe with your program, using glibc 2.28 and gcc 8.5.0.
This variation produces behavior more in line with what I think you expected:
// C program to show thread functions
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <semaphore.h>
sem_t sem;
void *func(void *arg) {
int x = pthread_detach(pthread_self());
sem_post(&sem);
printf("x = %d\n", x);
printf("Error description in second thread is : %s\n",strerror(x));
printf("Inside the thread\n");
pthread_exit(NULL);
}
void fun() {
pthread_t ptid;
pthread_create(&ptid, NULL, &func, NULL);
sem_wait(&sem);
int x = pthread_join(ptid, NULL);
printf("Error description in initial thread is: %s\n",strerror(x));
pthread_exit(NULL);
}
int main() {
sem_init(&sem, 0, 0);
fun();
return 0;
}
I modified the output a bit, but the main difference is that in this version, the initial thread waits to attempt to join the second one until the second signals via a semaphore that it has detached itself. This is the output I get:
x = 0
Error description in second thread is : Success
Inside the thread
Error description in initial thread is: Invalid argument
In this program, then, the pthread_join() call returns EINVAL, consistent with the target thread not being joinable.
This seems to reflect a race condition. Apparently, in the implementation I am testing and probably in yours as well, if pthread_join() proceeds far enough before the target thread detaches itself, then it waits for the target thread to terminate, even though eventually that thread is detached.
Note, however, that it is erroneous in the first place to attempt to both join and detach the same thread. POSIX makes only recommendations for the behavior in such case, while leaving it formally undefined (as far as POSIX is concerned). Glibc's pthread_join will detect the case where the target thread is already detached and fail with EINVAL, but the documentation doesn't say anything about what happens if a thread is detached while another one is trying to join it. Erroneous behavior does not necessarily produce predictable results.
When creating an pthread, pthread_create() is used. First parameter of this function is thread_id.
I tried to access this value pthread_self() but this gives something very big and not the numbers I gave while creating.
Is there a way to access this value?
for(int i = 0; i < necessaryThreadCount; i++){
pthread_create(&threadIDs[i], NULL, theFunction, (void*)&requiredStructre[i]);
}
my question is, how can i access the value of given threadID inside theFunction?
Solution:
I just added another variable to the struct I pass as parameter.
First parameter is pointer to thread_id which you need to declare first.
ID will get assigned after you create thread using pthread_create(). refer the below:
int main()
{
pthread_t thread; // declare thread
pthread_create(&thread, NULL, func, NULL);
printf("the thread id = %d\n", thread);
}
thread_id is for the new thread that is created. if you execute pthread_self() in the current thread it returns a different value from the newly created thread.
Hope the below example may help you to understand thread id creation:
[NOTE: not a good idea to have global pthread_t declared]
Example:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
pthread_t ctid;
void* thread_function(void* arg)
{
printf("Inside the thread\n");
printf("ctid: %ld, self: %ld", ctid, pthread_self());
// exit the current thread
pthread_exit(NULL);
}
void createthread()
{
pthread_create(&ctid, NULL, &thread_function, NULL);
printf("This line may be printed"
" before thread terminates\n");
// Waiting for the created thread to terminate
pthread_join(ctid, NULL);
pthread_exit(NULL);
}
// Driver code
int main()
{
createthread();
return 0;
}
I am working on a project in Cygwin. In an attempt to create multiple threads in C, and each thread calls another executable through the command line using the system() function, it turns out things are not working properly. Specifically, the code I have is like this:
#include <pthread.h>
#include <stdio.h>
#define NUM_THREADS 5
void *PrintHello(void *threadid)
{
long tid;
tid = (long)threadid;
system("date ");
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
for(t=0; t<NUM_THREADS; t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}
But it does not work. The error I get is segmenetation fault with stack overflows. Anyway has an idea on how to call other executables in the system shell in parallel by creating multiple threads?
Thanks.
Add this code :
for(t=0; t<NUM_THREADS; t++){
pthread_join(threads[t], NULL);
}
before
pthread_exit(NULL);
as called in main().
Several bugs here:
In the main() function, after you create the thread, you should use pthread_exit() to exit from all the individual thread. So exit() use is not right here.
In the end of the main() function, just before you terminate the main thread, call pthread_join() to wait for all the individual thread to terminate.
At the end after all the child threads have terminated, you can call exit() to terminate the process itself.
http://www.thegeekstuff.com/2012/04/terminate-c-thread/
That issue looks worth reporting to the Cygwin mailing list.
What you can do instead is to do away with threads and use fork()/exec() or spawn(_P_NOWAITO, ...) to create the child processes.
(spawn() actually is a family of functions; see /usr/include/process.h for details. Its use is recommended as it avoids Cygwin's high fork overhead.)
I'm sure I'm missing something basic, but I'm writing a program that fork()s several child processes, each of which create several pthreads. It seems that the pthread_create call never works from a child process. Here is sample code to explain what I mean:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
// Listen for a request from user proc i
void *wait_for_req(void *cvoid) {
int req;
int read_ret;
printf("new thread started\n");
pthread_exit(NULL);
}
void spawn_read_threads(int proc_num, int n) {
int i;
printf("About to spawn %d read threads\n", n);
for (i=0; i<n; i++) {
pthread_t *t;
printf("spawning new thread\n");
int create_result = pthread_create(t, NULL, wait_for_req, NULL);
printf("_create returned %d\n", create_result);
pthread_join(*t, NULL);
}
}
int main() {
if (!fork())
spawn_read_threads(0, 1);
}
The output of this program is
About to spawn 1 read threads
spawning new thread
But if I comment out if comment out if (!fork()):
About to spawn 1 read threads
spawning new thread
_create returned 0
new thread started
So why doesn't execution get through create_result in the first case?
And if this is useful:
rob#ubuntu:/mnt/hgfs/Virtual Machines$ uname -a
Linux ubuntu 2.6.32-24-generic #42-Ubuntu SMP Fri Aug 20 14:24:04 UTC 2010 i686 GNU/Linux
I can see one immediate problem with your code: pthread_create takes the address of an existing pthread_t variable and stores the new thread ID in it. You're passing an uninitialized pointer instead. You need to do something like:
pthread_t tid;
int create_result = pthread_create(&tid, NULL, wait_for_req, NULL);
I'd say you were just lucky when it worked once, because your current code essentially causes undefined behaviour.
Besides the errors you found in your answer, you are not supposed to call pthread_* from within the forked process. After, fork() only async-signal safe functions should be used. You must exec() first, and then you may create some pthreads.
pthread_t t;
printf("spawning new thread\n");
int create_result = pthread_create(&t, NULL, wait_for_req, NULL);
printf("_create returned %d\n", create_result);
pthread_join(t, NULL);
I'm working on an application for Linux in C which uses multiple threads. The threads which are spawned by the main function do most of the work, and therefore usually finish last. I'm seeing some strange behavior, and I believe it's due to the main thread terminating before the spawned threads have a chance to finish their jobs. Here's some sample code to illustrate what I'm talking about:
#define _POSIX_C_SOURCE 200112L
#define _ISOC99_SOURCE
#define __EXTENSIONS__
#define _GNU_SOURCE
#include <pthread.h>
#include <stdio.h>
void
my_cleanup(void *arg)
{
printf("cleanup: %s\n", (char *)arg);
}
void *
thread_stuff(void *arg)
{
printf("thread started\n");
pthread_cleanup_push(cleanup, "running");
if (arg)
pthread_exit((void *)2);
pthread_cleanup_pop(0);
pthread_exit((void *)2);
}
int
main()
{
int err;
pthread_t tid1, tid2;
err = pthread_create(&tid1, NULL, thread_stuff, (void *)1);
err = pthread_create(&tid2, NULL, thread_stuff, (void *)1);
sleep(10); /* change the value here if you want */
return SUCCESS;
}
When this code is run, the message from the cleanup function is printed twice, as it should be, but other times when it is run, I see the message printed only once sometimes, and other times I see it printed three times or not at all. You add in the sleep function in the main function to play with how long it takes the main function to terminate.
What can I do to make the program run as it should? I suspect it has something to do with joining to the children, but I don't entirely understand the concept of a join or how to apply it to this situation.
Thanks in advance!
Yes, you should "join" the threads. "Joining" a thread simply means waiting until the thread has terminated. In other words, you would do
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
to wait until both threads have terminated.
Edit: What to do if you have a child thread which, in turn, creates a "grandchild" thread? As a rule, whoever created the thread should wait for it to terminate ("join" it). So in this scenario, the child thread would call phtread_join on the grandchild thread, and the main thread would call join on the child thread.
I think you want to run pthread_join on each of the threads when your main thread completes -- this makes the main thread stop until the given thread finishes running. Other threads can still complete first though, so running pthread_join on every thread will prevent the main thread from terminiating until all of the others have terminated.
There is a definite problem if main() finishes before the threads it spawned if you don't call pthread_exit() explicitly. All of the threads it created will terminate because main() is done and no longer exists to support the threads.
By having main() explicitly call pthread_exit() as the last thing it does, main() will block and be kept alive to support the threads it created until they are done.
int main()
{
int err;
pthread_t tid1, tid2;
err = pthread_create(&tid1, NULL, thread_stuff, (void *)1);
err = pthread_create(&tid2, NULL, thread_stuff, (void *)1);
sleep(10); /* change the value here if you want */
/* Add the pthread_exit */
pthread_exit(NULL);
return SUCCESS;
}
Refer for more info here