如何用clone()替换pthread_join()和pthread_create()

时间:2014-05-07 07:20:55

标签: c linux pthreads

毫无疑问pthread_create()调用clone,但是可以修改有pthread_join()的程序吗?

Actualy我试图修改此代码以使用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");
}

首先我混淆了哪个标志用于克隆,然后我看了上面代码的strace输出并替换了我的主要功能

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");
}

但是这里主线程在新线程之前终止。 如何实现pthread_join功能?

1 个答案:

答案 0 :(得分:2)

正如alk所述,如果您使用CLONE_THREAD,则无法使用wait()等待线程完成。

  

使用CLONE_THREAD创建的新线程与clone()的调用者具有相同的父进程(即,类似于CLONE_PARENT),因此对getppid(2)的调用会为线程组中的所有线程返回相同的值。当CLONE_THREAD线程终止时,使用clone()创建它的线程不会发送SIGCHLD(或其他终止)信号;也不能使用wait(2)获得这种线程的状态。 (据说线程是分离的。)

man page也告诉我们:

  

在线程组中的所有线程终止后,线程组的父进程发送SIGCHLD(或其他终止)信号。

因此,如果您必须使用CLONE_THREAD,则可以使用pause()或其他一些信号处理机制等待整个线程组完成。

...
    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");
}

如果您不需要创建新的主题组(例如,不要使用CLONE_THREAD),您可以像以前那样使用wait()来恢复正常的&#39;流程处理:

...
    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 ); 
    }
}  

希望这有帮助!