好的,这就是我想要实现的目标。我希望forked进程的 threadRoutine 线程只从特定点开始执行,如注释所示//分叉进程的线程应该从这里开始执行。我对原始和分叉 threadRoutine 的堆栈使用相同的内存区域。但是我怀疑,因为我将 cp_thread 设置为1,所以分叉进程的 threadRoutine 执行 longjmp ,它的堆栈开始偏离< strong> 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);
}
答案 0 :(得分:1)
我认为你的问题与fork()
不重现子进程中的线程(存在于调用fork的父进程中)这一事实有关。在fork()之后,子进程中只存在一个线程。
此外,您应始终在setjmp
之前致电longjmp
,以便您的threadRoutine不正确。当然,你不应该 longjmp 进入另一个线程。
不要在没有大量预防措施的情况下使用 fork 的线程。详细了解pthread_atfork
。
我真的不明白你为什么要这么做。我仍然认为你不应该这样编码(或者你不能解释为什么要这样做,以及为什么)。
问候。