3

No doubt pthread_create() calls to clone, but is it possible to modify program having pthread_join()?

Actualy I am trying to modify this code to use clone()

#include <stdio.h>
#include <sched.h>
#include <pthread.h>

void *childfun (void *para)
{
    sleep(2);
    printf("child terminating\n");
}

int main (void)
{
    void * stackptr;
    pthread_t readthread;
    pthread_create(&readthread,NULL,childfun,NULL);
    pthread_join(readthread,NULL);
    printf("exit\n");
}

first I confused which flag to use for clone,then i watched strace output of above code and replaced my main function by

int main (void)
{
    int ctid;
    void *stackptr;
    stackptr = malloc(getpagesize());
    ctid = clone(childfun , stackptr+getpagesize() , CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|   CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID,NULL);
    printf("exit\n");
}

but here main thread is terminating before new thread. How to achieve pthread_join functioning?

user3452214
  • 175
  • 1
  • 3
  • 11
  • I think that `wait()` is the syscall you are looking for. Didn't you use `strace` for this? – rodrigo May 07 '14 at 07:28
  • I looked into the question linked above but I want to create thread instead of process (in case of process CLONE_VFORK will also work). – user3452214 May 07 '14 at 08:18
  • wait() is also useful but in case of process only not threads (as per my knowledge) – user3452214 May 07 '14 at 08:21
  • If you specify `CLONE_THREAD` when calling `clone()` there is no out-of-the-box possibility for the calling thread to detect when the created "thread" ends/ended. See `man 2 clone` for details. Btw: Uder Linux threads currently are implemented as (light weight) processes. You can retrieve their process-id using the system call `gettid()`. – alk May 07 '14 at 08:45

1 Answers1

3

As alk said, if you use CLONE_THREAD you can not use wait() to wait for your thread to finish.

A new thread created with CLONE_THREAD has the same parent process as the caller of clone() (i.e., like CLONE_PARENT), so that calls to getppid(2) return the same value for all of the threads in a thread group. When a CLONE_THREAD thread terminates, the thread that created it using clone() is not sent a SIGCHLD (or other termination) signal; nor can the status of such a thread be obtained using wait(2). (The thread is said to be detached.)

The man page also tells us:

After all of the threads in a thread group terminate the parent process of the thread group is sent a SIGCHLD (or other termination) signal.

So if you have to use CLONE_THREAD you could use pause() or some other signal handling mechanism to wait for the whole thread group to finish.

...
    ctid = clone(childfun , stackptr+getpagesize() , CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|   CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID,NULL);
    pause();
    printf("exit\n");
}

If you dont need to create a new thread group (e.g. don't use CLONE_THREAD), you can use wait() as you are used to from 'normal' process handling:

...
    ctid = clone(childfun , stackptr+getpagesize() , CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND |CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID,NULL);

     ctid = waitpid( ctid, 0, 0 );
     if ( ctid == -1 ){             
        perror( "waitpid" );
        exit( 3 ); 
    }
}  

Hope this helps!

mofoe
  • 3,634
  • 1
  • 16
  • 16
  • thank you I got answer that main thread will not get notify on termination of new created thread, but I think newly created thread will also be in the same thread group so using pause will stop running main thread as well as created thread so in my test program pause() is not showing the pthread_join() like effect. – user3452214 May 07 '14 at 11:57
  • It worked for me, apart from using pause(), you have to send some signal from the other thread, and handle it. – user2553863 Jun 30 '23 at 00:54