3

假设我想计算 n 个复数的乘积。

我要做的是计算(i=0;i<n/2)线程中 2*i 和 2*i+1 复数的乘积。即,将 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 行给出了段错误。我一直试图找出它有什么问题,但无济于事。我可能会犯一个根本上可怕的错误,但请帮帮我。

编辑1:可能是有史以来最愚蠢的错误。我不能像刚才那样全局分配内存。

我刚刚将 Malloc 插入到主函数中,程序就可以工作了。

4

3 回答 3

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;
    ...
于 2012-11-08T11:02:53.497 回答
1

很难弄清楚你的哪一行是第 45 行。

此外,这看起来非常错误:

struct arg *argv=malloc(5*sizeof(struct complex));

像这样的错误匹配类型很少是正确的,而且struct complex看起来一点也不像struct arg,所以这看起来真的很奇怪。另外,你不应该有一个全局命名argv,而你

于 2012-11-08T10:47:13.800 回答
0

首先,我不确定您分配的内存大小是否argv足够合理。其次,你修改这个argv东西,创建一个线程并立即覆盖它,很可能在线程接触到它之前。

于 2012-11-08T10:47:17.867 回答