【发布时间】:2011-10-28 15:00:20
【问题描述】:
好的,这就是我想要实现的目标。我希望分叉进程的 threadRoutine 线程仅从特定点开始执行,如注释所示//分叉进程的线程应该从这里开始执行。我为原始堆栈和分叉 threadRoutine 使用相同的内存区域。但我怀疑由于分叉进程的 threadRoutine 在我将 cp_thread 设置为 1 时确实执行了 longjmp,因此它的堆栈开始与 threadRoutine 的原始进程,所以它不能跳转到我想要的地方。
我该如何解决这个问题,即不要在分叉进程的 longjmp 之前将分叉进程的原始堆栈和 threadRoutine 的堆栈分开.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <setjmp.h>
pthread_attr_t attr;
int cp_thread = 0;
static jmp_buf buf;
pthread_barrier_t bar;
void make_jmp_if_req()
{
if ( cp_thread )
longjmp( buf, 1 );
}
void *threadRoutine(void *threadMsg)
{
size_t myStackSize;
void *stackAddr;
make_jmp_if_req();
printf("%d: TR:{stackAddr pointer = %lx, @threadRoutine = %lx}\n",
getpid(), stackAddr, threadRoutine );
pthread_attr_getstack(&attr,&stackAddr,&myStackSize);
setjmp( buf );
pthread_barrier_wait(&bar);
printf("%d: TR:stack address %p\n", getpid(), stackAddr);
printf("%d: TR:stack size is %x\n", getpid(), myStackSize);
//printf("%d\n",*((int *)stackAddr)); // <--------------------Causing segmentation fault..
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
size_t stacksize;
void *stackAddr;
int rc;
size_t i;
pthread_t thread;
pid_t pid;
pthread_attr_init(&attr);
// So that setjmp in the threadRoutine of the orignal process is called before
// longjmp from threadRoutine of the forked process.
pthread_barrier_init(&bar, NULL, 2);
stacksize = 0xC00000; //12582912;
stackAddr = malloc(stacksize);
printf("Main:{stackAddr = %lx}\n", stackAddr );
pthread_attr_setstack(&attr,stackAddr, stacksize);
pthread_attr_getstack(&attr,&stackAddr, &stacksize);
printf("Main:stack address %p\n",stackAddr);
printf("Main:stack size is %x\n",stacksize);
rc = pthread_create( &thread, &attr, threadRoutine, (void*)0 );
pthread_barrier_wait(&bar);
switch(pid = fork())
{
case -1:
printf("fork failed");
break;
case 0: // Child
printf( "Child pid() = %d\n", getpid() );
cp_thread = 1;
rc = pthread_create(&thread, &attr, threadRoutine,(void *)0);
break;
default:// Leader
printf( "Parent pid() = %d\n", getpid() );
//rc = pthread_create(&thread, &attr, threadRoutine,(void *)0);
}
if(rc)
{
printf("ERROR:return code from pthread_create %d\n",rc);
exit(-1);
}
pthread_exit(NULL);
}
【问题讨论】:
-
当您说“所以,请不要说不要使用它并以不同的方式做事”时,您是在要求人们不要回答您的问题。如果您想要一个有用的答案,请向我们展示您真正想要做什么,而不是提出“练习”。