2013-10-31 60 views
0

這是我第一次使用線程,我從一個簡單的程序開始。該程序需要n參數並創建n-2線程。事情是我得到了分段錯誤,我不知道爲什麼。使用線程時出現分段錯誤 - c

下面的代碼:

#include <stdio.h> 
#include <string.h> 
#include <pthread.h> 
#include <stdlib.h> 
#include <unistd.h> 

void * 
removeBytes (int i, char* argv[]) 
{ 
    printf ("%d, %s\n", i, argv[i]); 
    return NULL; 
} 


int main (int argc, char *argv[]) 
{ 

    pthread_t threads[argc - 3]; 
    int err; 
    int i; 
    int *ptr[argc - 3]; 

    printf ("argc = %d\n", argc); 

    for (i = 0; i < argc -3; i++) 
    { 
     err = 
     pthread_create (&(threads[i]), NULL, 
         removeBytes(i+1,&argv[i+1]), NULL); 
     if (err != 0) 
     { 
      printf ("\nCan't create thread: [%d]", i); 
     } 
     else 
     { 
      printf ("\nThread created successfully\n"); 
     } 
    } 

    for (i = 0; i < argc - 3; i++) 
    { 
     pthread_join (threads[i], (void **) &(ptr[i])); 
     printf("pthread_join - thread %d",i); 
    } 

    return 0; 
} 

例子:我的計劃被稱爲mythread所以當我運行它./mythread f1 f2 f3 f4 f5 f6輸出是:

argc = 6 

1,f2 
Thread created successfully 

2,f4 
Thread created successfully 
3, (null) 

爲什麼它會採取f2argv[1]f4argv[2]

UPDATE:

typedef struct{ 
    int i; 
    char* argv; 
    }Data; 

    void* removeBytes(void* arg){ 
    Data* data = (Data*)arg; 
    printf("%d, %s\n",data->i, data->argv); 
    free(data); 
    return NULL; 
    } 



    int main(int argc, char** argv){ 
    Data* data; 

    pthread_t threads[argc-3]; 

    int i; 
    int err; 
    for(i=0; i < argc-3;i++){ 
     data = (Data*)malloc(sizeof(Data)); 
     data->i=i+1; 
     data->argv=argv[i+1]; 
     err = pthread_create(&(threads[i]),NULL,removeBytes,data); 
     if(err != 0){ 
     printf("\nCan't create thread %d",i); 
     } 
     else{ 
     printf("Thread created successfully\n"); 
     } 
    } 

    return 0; 
    } 

爲./mythread F1 F2 F3 F4 F5 F6 F7 F8輸出爲:

5× 「線程創建成功」。它不打印我或argvi [i]。

+0

你的第二個程序沒有打印的原因是你刪除了'pthread_join'。您在編輯中呈現的解決方案存在內存泄漏。你可以在堆棧中分配這些'struct'(例如我在我的答案中所做的方式,但也可以使用其他選項)。 – dasblinkenlight

回答

0

您沒有使用正確pthread_create

pthread_create (&(threads[i]), NULL, 
         removeBytes(i+1,&argv[i+1]), NULL); 

在這裏,我們只是打電話removeBytes()和傳球的結果(NULL)爲pthread_create()參數。

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, 
          void *(*start_routine) (void *), void *arg); 

第三個參數應該是指向void* myThread(void*)函數的指針。如果要將參數傳遞給線程,則應使用void*參數並將其作爲pthread_create的第三個參數傳遞。

您可以查看this以瞭解如何使用pthread庫。

此外,你可能還需要將這樣的事情:

typedef struct { 
    int i; 
    char* argv; 
} Data; 

void * removeBytes (void* arg) 
{ 
    Data* data = (Data*) arg; 
    printf ("%d, %s\n", data->i, data->argv); 
    free(data); 
    return NULL; 
} 

,然後創建線程這樣的:

Data* data = (Data*)malloc(sizeof(Data)); 
data->i = i; 
data->argv = argv[i+1]; 
err = pthread_create (&(threads[i]), NULL, removeBytes, data); 
+0

它不打印argv和i。看來,線程不訪問removeBytes函數...我認爲 – MathMe

+0

@MoldovanRazvan [它的作品](http://pastebin.com/HqGe5c4v)與我在Linux上的GCC4.8,輸出是[this](http ://pastebin.com/BRzLTX3n)。你使用什麼編譯器/系統? – zakinster

0

隨着

pthread_create (&(threads[i]), NULL, 
        removeBytes(i+1,&argv[i+1]), NULL); 

要調用removeBytes()代替通過它作爲參數。

此外,您只能將一個參數傳遞給線程函數。所以你需要在一個結構中放置多個參數。喜歡的東西:

struct thread_args { 
    int i; 
    char *argv; 
} 

#your main code 
struct thread_args *thargs; 

for (i = 0; i < argc -3; i++) 
{ 
    thargs = malloc(sizeof(*thargs)); 
    thargs->i = i+1; 
    thargs->argv = argv[i+1]; 
    err = 
    pthread_create (&(threads[i]), NULL, 
        removeBytes, thargs); 
    if (err != 0) 
    { 
     printf ("\nCan't create thread: [%d]", i); 
    } 
    else 
    { 
     printf ("\nThread created successfully\n"); 
    } 
} 
#make sure to free up thargs as well. 

和更新線程功能

void *removeBytes (void *arg) 
{ 
    int i; 
    char *argv; 
    struct thread_args *thargs = (struct thread_args *) arg; 
    i = thargs->i; 
    argv = thargs->argv; 
    printf ("%d, %s\n", i, argv); 
    return NULL; 
} 
+0

謝謝你的回答!我不知道爲什麼,但輸出只是「胎面創建成功」。它不打印我和argv [i]。我認爲它不訪問removeBytes或其他東西... – MathMe

+0

@MoldovanRazvan,你有正確更新代碼嗎?也許你可以向我們展示更新的代碼。 – Rohan

+0

我更新了代碼 – MathMe

0

有一個在

問題
pthread_create (&(threads[i]), NULL, 
        removeBytes(i+1,&argv[i+1]), NULL); 

pthread_create語法是

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, 
         void *(*start_routine) (void *), void *arg); 

它需要開始常規的CAL lback。在你的情況下,你正在調用產生前返回NULL的主線程中的removeBytes。所以,回調是NULL。

所以,相應地修改removeBytes根據自己的需要,並調用

在pthread_create(&(線程[I]),NULL, removeBytes,argv的第[i + 1]);

0

它需要F2將以argv [1]和f4將以argv [2],只是因爲當傳遞&的argv [I + 1]你確實傳遞指針到第(i + 1)個數組和你的元件也傳遞i + 1作爲索引。首先你會在removeBytes中得到[f1,f2,f3,f4,f5,f6]。所以如果你有argv等於[mythread,f1,f2,f3,f4,f5,f6]而當你訪問i + 1 = 1元素時,你會得到f2。下一次你會得到[f2,f3,f4,f5,f6]和i + 1 = 2,所以你會得到f4