2011-10-28 9 views
1

ここでは達成したいことがあります。 threadRoutineフォークされたプロセスのスレッドは、コメントで示される特定のポイントからの実行を開始するだけです//フォークされたプロセスのスレッドはここからから実行を開始する必要があります。私は元のスタックのために同じメモリ領域を使用します。threadRoutine。しかし、私はフォークプロセスのthreadRoutineは私が1にcp_threadを設定するようlongjmpのを実行しないので、そのスタックは元のプロセスのthreadRoutineから分岐し始め、私が意図したところそれがジャンプすることはできませんと思われます。私はこの問題を解決するにはどうすればよい分岐したプロセスからのlongjmp

は、それはフォークプロセスのlongjmpをのprecenceに元のスタックやフォークプロセスの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); 
} 
+1

「あなたはこれを使わないと言って、違うことをしてはいけません」と言うと、人々はあなたの質問に答えないように頼んでいます。役に立つ答えが必要な場合は、「運動」を提示するのではなく、実際に何をしようとしているのかを見せてください。 – larsks

答えて

1

私はあなたの問題はfork()が子プロセス内のスレッド(フォークを呼び出して、親プロセスに存在)を再生していないという事実に関連していると思います。 fork()の後、子プロセスにはただ1つのスレッドしか存在しません。

longjmpの前に常にsetjmpを呼び出して、threadRoutineが正しくないようにする必要があります。もちろん、あなたはlongjmpに別のスレッドを入れてはいけません。

フォークのスレッドを使用しないでください。 pthread_atforkについて詳しくは、こちらをご覧ください。

そして、私はなぜあなたがこのすべてをしたいのか分かりません。私はまだあなたがそのようにコード化すべきではないと信じています。

よろしくお願いいたします。

+0

はい私は知っている、これが私がこの運動をしている理由です。分岐したプロセスでデッドスレッドを復活させることができるかどうかを確認する。あなたは正しい、setjmpはlongjmpの前に呼び出されるべきではないかもしれません。おそらく最初のpthread_createの後と元のスレッドからsetjmpを行った後にバリアを置くべきです。私がここでやろうとしているのは、元のスレッドと、フォークされたプロセスとCPU状態のスタックを同じスタックにして、setjmp/longjmpで保存しようとしていることです。 – MetallicPriest

+0

今、バリアを置いているので、元のプロセスのthreadRoutineのsetjmpが、forkされたプロセスのthreadRoutineからlongjmpの前に呼び出されます。 – MetallicPriest

+0

このメカニズムを使用してスレッドを復活させることは完全には定義されていません。 setjmp/longjmpは、同じスレッド内でのみ使用するように定義されており、スレッド間で使用するのに十分な状態を保存しません。フォーク後にサブプロセス内の親プロセスで実行されていたスレッドを再作成しようとする場合は、コルーチンを使用して設計する必要があります。コルーチンでは、フォーク前にすべてのスレッドを強制的に「結合」し、状態にする。一般的に、それをサポートしていないOS上でマルチスレッドプロセスのforkallを実装しようとすると、suspend/resumeを処理するのと同じようになります – Petesh