毫无疑问 pthread_create() 调用克隆,但是是否可以修改具有 pthread_join() 的程序?
实际上我正在尝试修改此代码以使用 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功能?
作为alk说,如果你使用 CLONE_THREAD
你不能使用 wait()
来等待你的线程完成。
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.)
man page还告诉我们:
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.
因此,如果您必须使用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()
,就像你习惯的那样' 进程处理:
...
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 );
}
}
希望这对您有所帮助!