我写了一个输出素数的多线程Pthread程序。该程序的工作原理如下:用户将运行该程序并在命令行中输入一个数字。然后程序将创建一个单独的线程,输出小于或等于用户输入的所有素数。 代码:
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<math.h>
#include<string.h>
#define true 1
#define false 0
void* print_prime(void* arg)
{
int temp;
temp = *((int*)arg);//If I change it to 'temp = (int)arg',it runs well
int flag;
int i,j;
for(i = 2 ; i <= temp ; i++)
{
flag = true;
for(j = 2 ; j <= (int)sqrt(i) ; j++)
{
if(i%j == 0)
{flag = false;break;}
}
if(flag == true)
printf("%d\n",i);
}
}
int main(int argc,char *argv[])
{
pthread_t tid;
pthread_attr_t attr;
pthread_attr_init(&attr);
if(argc != 2)
{perror("Parameters not enough");exit(0);}
int arg = atoi(argv[1]);
if(pthread_create(&tid,&attr,print_prime,(void*)arg))
{perror("Pthread created not successfully");exit(0);}
pthread_join(tid,NULL);
return 0;
}
当我在终端中写道:./pthread_test 10
时,发生segmentation fault(core dump)
。我使用dmesg
和addr2line -e pthread_test 0xxxxxx
来查找错误。它转向指令{{ 1}}。
在temp = *((int*)arg)
中,我已将pthread_create(&tid,&attr,print_prime,(void*)arg)
转换为arg
类型变量,为什么我使用void*
时出错?
答案 0 :(得分:2)
当您将int作为指向void的指针传递时,它不会改变您发送int值而不是其地址的事实。当你执行*(int *)时,你试图获得你将从参数void获得的地址内容(指向int的指针)。显然,因为你在int中发送了值而不是它的地址,所以它不起作用。尝试一下(void *)(&amp; arg)。但我认为这是毫无意义的铸件。你为什么要做*(int *)?有什么特别的原因吗?你明白指向void的概念吗?
答案 1 :(得分:1)
来自函数的定义
int pthread_create(pthread_t *thread,
const pthread_attr_t *attr,
void *(*start_routine) (void *),
void *arg);
第四个参数的类型是void*
,但在您的代码中,您编写了(void*)arg
,所以这是错误的。
你可以改为:
pthread_create(&tid,&attr,print_prime,(void*)&arg)
原因arg
中int
,值可能是100
(只是一个例子,您的输入值)。如果您使用(void*)arg
,则表示您希望将100(int type)
更改为void*
类型。所以你的代码有问题,因为你的代码读取了memmory地址100
。应该将值100
的地址传递给pthread_create
,因此您需要编写(void*)&arg
。
答案 2 :(得分:0)
在这里传递值
如果(在pthread_create(安培; TID,&安培; ATTR,print_prime,(无效*)ARG))
不是地址。所以你将一些值转换为void指针并在另一个函数中取消引用它。所以这引起了这个问题。
if(pthread_create(&amp; tid,&amp; attr,print_prime,(void *)&amp; arg))是正确的