说我想计算n个复数的乘积。
我要做的是计算线程中2 * i和2 * i + 1 (i=0;i<n/2)
复数的乘积。即,将2个数字聚集在一起并计算其产品,因此我将获得n / 2个产品。然后再对这些n / 2产品执行相同的操作。等等,继续进行,直到n的值为1。
这是我的代码
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
struct complex{
int a;
int b;
};
struct complex arr[1000];
struct arg {
struct complex arr1;
struct complex arr2;
int i;
};
//struct arg *argv;
struct arg *argv=malloc(sizeof(struct arg));
void *multiplier(struct arg *argv)
{
int real,imaginary;
real=(argv->arr1.a)*(argv->arr2.a)-(argv->arr1.b)*(argv->arr2.b);
imaginary=(argv->arr1.a)*(argv->arr2.b)+(argv->arr1.b)*(argv->arr2.a);
arr[argv->i].a=real;
arr[argv->i].b=imaginary;
printf("real=%d imaginary=%d no=%d\n",real,imaginary,argv->i);
pthread_exit(0);
}
int main(void)
{
int n,i,j,flag=0,q;
pthread_t tid;
pthread_attr_t attr;
pthread_attr_init(&attr);
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d + i%d",&arr[i].a,&arr[i].b);
for(i=0;i<n;i++)
printf("%d + i%d\n",arr[i].a,arr[i].b);
while(n!=0)
{
if(n%2==1)
flag=1;
else
flag=0;
for(i=0;i<n/2;i++)
{
argv->arr1.a=arr[2*i].a; /* SEG FAULT HERE */
argv->arr1.a=arr[2*i].b;
argv->arr2.a=arr[2*i+1].a;
argv->arr2.a=arr[2*i+1].b;
argv->i=i;
pthread_create(&tid,&attr,multiplier,(void *) argv);
}
pthread_join(tid,NULL);
if(flag==1)
{
arr[n/2].a=arr[n-1].a;
arr[n/2].b=arr[n-1].b;
}
n=n/2;
}
return(0);
}
然而,我的代码在第45行给了我seg错误。我一直在试图弄清楚它有什么问题,但无济于事。我可能会犯一个根本可怕的错误,但确实帮助了我。
编辑1: 可能是有史以来最愚蠢的错误。 我不能像我刚才那样全局分配内存。
我刚将Malloc插入主函数,程序正常运行。
答案 0 :(得分:2)
每个线程都需要通过argv
传入的自己的内存,而不是覆盖其他线程数据。
所以你可能会动摇这一行
struct arg * argv = malloc(sizeof(struct arg));
到这里:
for(i = 0; i < n/2; ++i)
{
struct arg * argv = malloc(sizeof(*argv));
argv->arr1.a = arr[2*i].a;
同时检查调用malloc()
的结果可能不是一个坏主意。
然后让线程函数free()
完成它的内存:
void * multiplier(struct arg * argv)
{
...
free(argv);
pthread_exit(0);
}
传递给pthread_create()
的线程函数也被定义为:
void *(*)(void *)
所以你应该这样宣布你的:
void * multiplier(void * pvargv)
{
struct arg * argv = pvargv;
...
答案 1 :(得分:1)
很难弄清楚哪一行是第45行。
此外,这看起来非常错误:
struct arg *argv=malloc(5*sizeof(struct complex));
错误匹配类型很少是正确的,struct complex
看起来不像struct arg
,所以这看起来很奇怪。此外,当你
argv
的全局
答案 2 :(得分:0)
首先,我不确定您为argv
分配的内存大小是否足够清晰。其次,你修改这个argv
的东西,创建一个线程并立即覆盖它,可能是在线程开始之前。