Ole Gooner
Ole Gooner

Reputation: 567

Threads and parallel programming

Say I want to compute the product of n complex numbers.

What I'm trying to do is that compute the product of the 2*i and 2*i+1 (i=0;i<n/2) complex numbers in threads. ie, clump 2 numbers together and compute their product, therefore I shall get n/2 products. Then again perform the same action on these n/2 products. So on and so forth, and carry on till the value of n is 1.

Here's my code

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

However my code gives me seg fault at line 45. I've been trying to figure out what's wrong with it but to no avail. I probably might be making a fundamentally horrendous error, but do help me out.

EDIT 1: Probably the most stupid error ever. I can't allocate memory globally like the way I just did.

I just inserted the Malloc into the main function and the program works.

Upvotes: 3

Views: 173

Answers (3)

alk
alk

Reputation: 70971

Each thread needs it's own memory passed in via argv to not overwrite the other thread data.

So you might liek to move this line

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

to here:

for(i = 0; i < n/2; ++i)
    {
        struct arg * argv = malloc(sizeof(*argv));
        argv->arr1.a = arr[2*i].a; 

Also checking the result of the calls malloc() might not be a bad idea.


Then let the thread function free() its memory when its done with it:

void * multiplier(struct arg * argv)
{
    ...

    free(argv);

    pthread_exit(0);
}

Also the thread function to be passed to pthread_create()is defined as:

void *(*)(void *)

So you shall declare yours this way:

void * multiplier(void * pvargv)
{
    struct arg * argv = pvargv;
    ...

Upvotes: 2

Michael Krelin - hacker
Michael Krelin - hacker

Reputation: 143189

First, I'm not sure if the memory size you allocate for argv is sane enough. Second, you modify this argv thing, create a thread and immediately overwrite it, probably, before the thread even gets its hands on it.

Upvotes: 0

unwind
unwind

Reputation: 399949

It's pretty hard to figure out which of your lines is line 45.

Also, this looks very wrong:

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

It's very rarely correct to mis-match types like that, and struct complex looks nothing like struct arg, so this really seems strange. Also, you shouldn't have a global named argv while u

Upvotes: 1

Related Questions