[英]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.