簡體   English   中英

使用線程時出現分段錯誤-c

[英]segmentation fault when using threads - c

這是我第一次使用線程,我從一個簡單的程序開始。 該程序采用n參數並創建n-2線程。 問題是我遇到了細分錯誤,但我不知道為什么。

這是代碼:

#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)

為什么將f2作為argv[1]f4作為argv[2]

更新:

 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 x“線程創建成功”。 它不打印i或argvi [i]。

您沒有正確使用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);

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;
} 

有問題

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);

它以啟動例程作為回調。 在您的情況下,您是在生成並返回NULL之前在主線程中調用removeBytes。 因此,回調為NULL。

因此,根據需要修改相應的removeBytes並致電

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

它僅將f2用作argv [1],將f4用作argv [2]只是因為當您傳遞&argv [i + 1]時,您實際上傳遞了指向數組第(i + 1)個元素的指針,並且還傳遞了i + 1作為索引。

因此,如果您首先使argv等於[mythread,f1,f2,f3,f4,f5,f6],您將在removeBytes中獲得[f1,f2,f3,f4,f5,f6]。 當您訪問i + 1 = 1元素時,將得到f2。 下次您會得到[f2,f3,f4,f5,f6]並且i + 1 = 2所以您會得到f4

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM