毫无疑问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功能?
答案 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 );
}
}
希望这有帮助!