1

the question is: to write program with global integer one dimensional array A of size N by a factor M. using threads , the main thread initializes A and M with random integers, creates N threads such that the ith thread finds Ai = M * Ai, and finally prints the array A.

my problem i am having an error with array initialization also i am not sure about making the threads in correct way. i hope i explained my problem clearly.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int M;
int [10] A;

void *run(void *t)
{
   A[(int)t]=A[(int)t]*M;
   pthread_exit(NULL);
}


int main()
{
   pthread_t [10] th;
   srand(time(0))%20;
   M=rand();
   int t;
   for(t = 0; t < 10; t++)
   {
     pthread_create(&th[t], NULL, run, (void *)t);
   }

   int j;
   for(j=0;j<10;j++)
    A[j]=j;

   int i;
   for(i = 0; i < 10; i++)
   {
     pthread_join(th[i], NULL);
     printf("%d:  %d\n", i,A[i]);
   }

   printf("Thread main\n");
   pthread_exit(NULL);
}

these are the errors:

que1.c:5: error: expected identifier or ‘(’ before ‘[’ token
que1.c: In function ‘run’:
que1.c:9: error: ‘A’ undeclared (first use in this function)
que1.c:9: error: (Each undeclared identifier is reported only once
que1.c:9: error: for each function it appears in.)
que1.c: In function ‘main’:
que1.c:16: error: expected identifier or ‘(’ before ‘[’ token
que1.c:17: error: void value not ignored as it ought to be
que1.c:22: error: ‘th’ undeclared (first use in this function)
que1.c:27: error: ‘A’ undeclared (first use in this function)
1
  • Can you correct your code above too? Commented Mar 18, 2011 at 6:57

3 Answers 3

4

It looks like you're having a Java background (or D), as you wrote int [10] A. You may read this as A is a variable to a array of 10 ints type object. But in C those things are a little bit different. In C there are only individual primitive variables, and they may be arranged in sets of continous memory, which is then called an array. That's why the syntax int A[10]; was choosen, which means: A is a pointer to integer, pointing the beginning of automatically allocated storage for 10 integers.

The next problem with your program, though the compiler will not report it is passing an integer through a void* type. In C every pointer can be converted to some integer, but not all integer values make pointers. Pointers in C are abstract things: Most implementations choose to use the memory address as their integer representation. But it would be as valid to map them through a injective LUT. So some integer values may not map to a pointer and thus not properly transfer. You should really pass a real pointer.

Also your use of threads is suboptimal. In your case you're trashing cache lines like mad and the switching overhead will eat up any parallelization gain. As a rule of thumb you should create no more than 'number of CPU cores' + 2 threads. Taking all this into account you could do the following:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

/* some prime number, so show what happens with uneven work sizes */
#define ELEMENTS 17

int M;
int A[ELEMENTS];

struct WorkletInfo {
   int *data_base;
   int count;
};

void *worklet(void *t)
{
   int i;
   struct WorkletInfo *wi = t; /* note: no cast here */
   if(!wi)
       return 0;

   for(i=0; i < wi->count; i++)
       wi->data_base[i] *= M;

   return wi;
}

#define N_CPUS 4
#define NUM_THREADS (N_CPUS+1)

int main(int argc, char *argv[])
{
   int t, ec;
   pthread_t th[NUM_THREADS];
   int remaining_elements;
   int const elements_per_worklet = ELEMENTS/NUM_THREADS;

   srand(time(0));
   M=rand();

   /* you must initialize the data a thread will access before starting the thread */
   for(t = 0; t < ELEMENTS; t++)
       A[t]=t+1; /* 0 * x = 0, so give it some nonzero value */

   remaining_elements = ELEMENTS - (elements_per_worklet*NUM_THREADS);
   ec = 0;
   for(t = 0; t < NUM_THREADS; t++)
   {
       struct WorkletInfo *wi = malloc(sizeof(*wi));
       wi->data_base = &A[ec];

       wi->count = elements_per_worklet;
       if(t<remaining_elements) {
           wi->count++;
       }
       ec += wi->count;

       pthread_create(&th[t], NULL, worklet, wi);
   }

   ec = 0;
   for(t = 0; t < NUM_THREADS; t++)
   {
       int i;
       struct WorkletInfo *wi;
       void *retval;
       pthread_join(th[t], &retval);

       if(!retval)
           continue;

       wi = retval;

       for(i = 0; i < wi->count; i++, ec++)
           printf("worklet %d, worklet element %d => total element %d:  %d\n", 
              t, i, ec, 
          wi->data_base[i]);

       free(wi);
       }

   printf("Thread main\n");

   return 0;
}

The output of this program looks like this:

worklet 0, worklet element 0 => total element 0:  300787748
worklet 0, worklet element 1 => total element 1:  601575496
worklet 0, worklet element 2 => total element 2:  902363244
worklet 1, worklet element 0 => total element 3:  1203150992
worklet 1, worklet element 1 => total element 4:  1503938740
worklet 1, worklet element 2 => total element 5:  1804726488
worklet 1, worklet element 3 => total element 6:  2105514236
worklet 2, worklet element 0 => total element 7:  -1888665312
worklet 2, worklet element 1 => total element 8:  -1587877564
worklet 2, worklet element 2 => total element 9:  -1287089816
worklet 3, worklet element 0 => total element 10:  -986302068
worklet 3, worklet element 1 => total element 11:  -685514320
worklet 3, worklet element 2 => total element 12:  -384726572
worklet 3, worklet element 3 => total element 13:  -83938824
worklet 4, worklet element 0 => total element 14:  216848924
worklet 4, worklet element 1 => total element 15:  517636672
worklet 4, worklet element 2 => total element 16:  818424420
Thread main exit
Sign up to request clarification or add additional context in comments.

Comments

2

Your first problem is purely a syntax one. This is not valid C:

int [10] A;

It should be:

int A[10];

Similarly for pthread_t [10] th;.

3 Comments

you are right, this is totally correct . i corrected my code but still there is a single error in line 17.
error says: que1.c:17: error: void value not ignored as it ought to be
@Tomy: The error messages are telling you where the error messages are! If the first error message refers to line 17, then take a look at line 17 and work out what's wrong with it. No offence intended, but if you don't know how to interpret the error messages and work what's wrong with your syntax, then you probably shouldn't be trying to write a multithreaded C program yet...
2

In addition to @Oli Charlesworth's answer, srand does not return any values, it's declared as void, so you can't write srand(time(0)) % 20.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.