2016-12-01 8 views
1

私はCとLinuxで非常に新しく、英語は母国語ではありません。申し訳ありません。thread_create関数の実装とテスト

私はthread apiを実装している学校プロジェクトに取り組んでおり、clone()を使ってthread_create()関数を作っています。 問題は、私がthread_create(&tid1, NULL, (void *)Testcase1, 0);に電話すると、 は新しいスレッドを作成しますが、TestCase1にはthread_createも含まれていて、別のスレッドを作成していないようです。私は以下の私のコードで説明しましょう:

int foo(void* arg){ 
    printf("Hii"); 
    return 0; 
} 
int  thread_create(thread_t *thread, thread_attr_t *attr, void *(*start_routine) (void *), void *arg) 
{ 
    void* stack; 

    stack= malloc(STACK_SIZE); 
    pid_t pid; 

    if(stack==0) 
    { 
     perror("malloc : could not allocate stack"); 
     exit(1); 
    } 
    pid = clone(&foo ,(char*)stack+STACK_SIZE,SIGCHLD|CLONE_VM|CLONE_SIGHAND|CLONE_FS|CLONE_FILES,0); 
    if(pid == -1) 
    { 
     perror("clone"); 
     exit(2); 
    } 
    kill(pid, SIGSTOP); 

    Thread* newTCB = (Thread*)malloc(sizeof(Thread)); 
    newTCB->stackSize = malloc(STACK_SIZE); 
    newTCB->pid = pid; 
    newTCB->status = THREAD_STATUS_READY; 

    rEnqueue(newTCB); 
    rPrintqueue(); 

    free(stack); 
    printf("Child thread returned and stack freed.\n"); 
    return 0; 
} 

そして、これは以下の私のテストコードです:

thread_create(&tid1, NULL, (void*)TestCase1, 0); 

TestCase1()以下:

int Tc1ThreadProc(int param) 
{ 
    int tid = 0; 
    int count = 0; 

    tid = thread_self(); 

    count = 3; 
    while (count > 0) 
    { 
     /* sleep for 1 seconds */ 
     sleep(2); 
     printf("Tc1ThreadProc: my thread id (%d), arg is (%d)\n", tid, param); 
     count--; 
    } 
} 
void TestCase1(void) 
{ 
    thread_t tid[TOTAL_THREAD_NUM]; 

    thread_create(&tid[0], NULL, (void*)Tc1ThreadProc, (int*)1); 
    thread_create(&tid[1], NULL, (void*)Tc1ThreadProc, (int*)2); 
    thread_create(&tid[2], NULL, (void*)Tc1ThreadProc, (int*)3); 

    while(1){} 

    return ; 
} 

"Tc1ThreadProc: my thread id (%d), arg is (%d)\n" 3回を印刷するようになっていますが、それはfoo()の呼び出しのためにだけである"Hii"を印刷します。 これを修正するにはどうすればよいですか?

+0

問題がいくつかあります:あなたの 'thread_create'関数は、関数へのポインタ*を求めています。あなたのスレッド関数 'Tc1ThreadProc'は、' sizeof(int) 'が' sizeof(void *) 'と異なる場合があり、*未定義の振る舞いにつながる場合、引数として 'int'をとります。あなたの 'thread_create'関数は' foo'を呼び出すためにハードコードされています。あなたが渡す関数ではありません。あなたは 'thread'引数を初期化しません。最後に、作成関数内のスタックを解放するので、スレッドにはスタックがありません。 –

+0

foo()の代わりにどの関数を呼び出す必要がありますか? @Someprogrammerdude – user19283043

+0

'clone'呼び出しでは、' thread_create'に渡された関数へのポインタを渡すべきです。 –

答えて

1

あなたは、引数としての「thread_createを」「TestCase1を」関数へのポインタを渡しますが、内部の「thread_createは」あなたがすべてでそれを使用しないでください:あなたはだけで「クローン」システムコールを呼んでいる

thread_create(&tid1, NULL, (void*)TestCase1, 0); 

"foo"関数へのポインタ。 "thread_create"から "TestCase1"ポインタの名前が "start_routine"なので、同様の "clone"システムコールを呼び出す必要がありますが、 "foo"へのポインタで "TestCase1"へのポインタを渡す必要があります。何かのように:

pid = clone(start_routine, (char*) stack + STACK_SIZE, SIGCHLD | CLONE_VM | CLONE_SIGHAND | CLONE_FS | CLONE_FILES, 0); 
+0

完全に理解されています!どうもありがとう! – user19283043

+0

そして、親プロセスのSIGCHLDルーチンで終了すると、子プロセスのスタックメモリを解放する必要があります。 –

+0

次に、thread_create()の最後にスタックメモリを解放する必要がありますか? – user19283043