2016-12-01 104 views
1

我在C和Linux中很新,英文不是我的母語。提前對不起。執行和測試thread_create函數

我正在執行一個學校項目,它正在實現線程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次,但它僅打印"Hii",這是因爲致電foo()。 我該如何解決這個問題?

+0

有幾個問題:你的'thread_create'函數需要一個指向函數指針的指針;當sizeof(int)'可能與sizeof(void *)'不同,導致* undefined行爲時,你的線程函數'Tc1ThreadProc'接受'int'作爲參數。你的'thread_create'函數被硬編碼來調用'foo'而不是你傳遞給它的函數。你不會初始化'thread'參數;最後你在創建函數中釋放堆棧,所以線程沒有堆棧。 –

+0

那麼我需要調用哪個函數而不是foo()? @Someprogrammerdude – user19283043

+0

對於'clone'調用,您應該將指針傳遞給傳遞給'thread_create'的函數。 –

回答

1

您傳遞函數指針「TestCase1」作爲參數傳遞給「thread_create」,但裏面的「thread_create」你根本就不使用它:

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

你打電話「克隆」系統調用只能用指向「富」功能的指針。 從「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