2

I'm a newbie in Pthread programming.

I've been trying to use Pthread in a very simple way like this code below, and it works well in my CodeBlock as I already included the dll and bin files.

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

void *printNumber(void *x);

int main(){
    pthread_t threadA, threadB, threadC, threadD;
    pthread_create(&threadA, NULL, printNumber, (void *)"Sponge");
    pthread_create(&threadB, NULL, printNumber, (void *)"Star");
    pthread_create(&threadC, NULL, printNumber, (void *)"Squid");
    pthread_create(&threadD, NULL, printNumber, (void *)"Crab");
    pthread_exit(NULL); 
    return 0;
}

void *printNumber(void *x){
    char* id = (char*)x;
    int i;
    for(i=0;i<100;i++){
        printf("Thread %s: printing integer value %i\n", id, i);
    }
    pthread_exit(NULL);
}

And then I write another simple program to add 2 arrays (arrayA + arrayB) into arrayC, using Pthread. Here's my simple code. Everything was hardcoded, no looping and such in the main(), because I want to make it as simple as possible for me to understand how to create a single Pthread.

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

#define SIZE 16
#define UPPER_RAND 100
#define NUM_THREADS 4

// HEADER PROCEDURES    
void randomGenerator(int arr[]);
void printArray(int arr[]);
void *addArrayPthread(void *x);

typedef struct {
    int startIdx;
    int arrC[SIZE], arrA[SIZE], arrB[SIZE];
} someType;

int main(){
    printf("A Simple Program To Add Arrays Using PThread\n");
    int arrayA[SIZE];
    int arrayB[SIZE];
    int arrayC[SIZE];

    randomGenerator(arrayA);
    printArray(arrayA);

    randomGenerator(arrayB);
    printArray(arrayB);

    someType *w,*x,*y,*z;
    w = (someType*) malloc(sizeof(someType));
    x = (someType*) malloc(sizeof(someType));
    y = (someType*) malloc(sizeof(someType));
    z = (someType*) malloc(sizeof(someType));

    (*w).startIdx = 0;
    (*w).arrA = arrayA;
    (*w).arrB = arrayB;
    (*w).arrC = arrayC;

    (*x).startIdx = 4;
    (*x).arrA = arrayA;
    (*x).arrB = arrayB;
    (*x).arrC = arrayC;

    (*y).startIdx = 8;
    (*y).arrA = arrayA;
    (*y).arrB = arrayB;
    (*y).arrC = arrayC;

    (*z).startIdx = 12;
    (*z).arrA = arrayA;
    (*z).arrB = arrayB;
    (*z).arrC = arrayC;


    pthread_t threadA, threadB, threadC, threadD;
    pthread_create(&threadA, NULL, addArrayPthread, (void *)w);
    pthread_create(&threadB, NULL, addArrayPthread, (void *)x);
    pthread_create(&threadC, NULL, addArrayPthread, (void *)y);
    pthread_create(&threadD, NULL, addArrayPthread, (void *)z);

    pthread_join(threadA, NULL);
    pthread_join(threadB, NULL);
    pthread_join(threadC, NULL);
    pthread_join(threadD, NULL);

    return 0;
}


//=====================================================================================//

void randomGenerator(int arr[]){
    printf("Generating random value for the array...\n");
    int i;
    for (i=0;i<SIZE;i++){
        arr[i] = (rand() % UPPER_RAND);
    }
}

void printArray(int arr[]){
    printf("Display the array value...\n");
    int i;
    printf("[");
    for (i=0;i<SIZE;i++){
        printf("%i, ",arr[i]);
    }
    printf("]\n");
}

void *addArrayPthread(void *x){
    someType *p = (someType *) x;
    printf("Adding to arrays, starting from index #%i\n",(*p).startIdx);
    int blockSize = SIZE/NUM_THREAD;
    int end = (*p).startIdx + blockSize;
    int i;
    for (i=(*p).startIdx;i<end;i++){
        (*p).arrC[i] = (*p).arrA[i] + (*p).arrB[i];
    }
}

I got 12 error messages around these lines: (*x).arrA = arrayA; and such

||In function `int main()':|
\pth_array.c|58|error: ISO C++ forbids assignment of arrays|

Here's my questions:

  1. Why the forbidden assigment of arrays? And how to solve it?
  2. In the first program above, I put pthread_exit(NULL) twice: in main() and in the void* function. I suppose I only need to put it once. So where do exactly I have to put it? In main() or in the void* function?
  3. Is it mandatory to put pthread_join in the main() before return 0?

Thank you in advance. Your explanation will be a big help for me.

Thanks

P.S.: I post another similar question (about matrix) in the section below.

8
  • OT: There is the -> operator. Commented Mar 2, 2013 at 17:55
  • The compiler is complaining that an array is not allowed on the right hand side of an assignment operator. What are you trying to do with each of the marked lines of code? Commented Mar 3, 2013 at 0:29
  • Also, what is someType? Commented Mar 3, 2013 at 0:30
  • @Code-Guru: So what is allowed on the right hand side of an assignment operator? Sometype is a new type which will be converted to (void *) as an argument for pthread_create. Actually, I wasn't sure about what happened (in the memory stack) behind the code I wrote. If you will, please take a look at my next post (new question about matrix assignment). Commented Mar 3, 2013 at 0:54
  • @izza Things which are allowed on the right hand side of an assignment operator are called rvalues, as opposed to lvalues which are allowed on the left hand side. I suggest that you google these two terms for a more detailed explanation. Commented Mar 5, 2013 at 1:53

2 Answers 2

3

What about something like :

typedef struct {
    int startIdx;
    int *arrC, *arrA, *arrB;
} someType;

[...]

x->arrA = arrayA
[...]

pthread_join is needed because you want to wait for every thread to be finished before exiting the application.

Sign up to request clarification or add additional context in comments.

2 Comments

@ Anthony Catel: Before I saw your answer, I was thinking to change my struct according to a sample from a link I found (computational.engineering.or.id/Matrix/Perkalian) like this: typedef struct { int startIdx; int (*arrC)[SIZE], (*arrA)[SIZE], (*arrB)[SIZE]; } someType; But your suggestion seems easier to understand. Thanks.
@ Anthony Catel: Your suggestion work very well...!!! Thanks a lot :D. I'm going to write a matrix mult using Pthread now.
0

Well,

  1. You are not allowed to directly copy arrays in C. It has been explained here quite well.
  2. The exact functinality of pthread_exit is clearly stated here; Examples are also available here. That is to say that the call should be placed in printNumber(void *x) and not in main().
  3. The exact functinality of pthread_join is clearly stated here. So to pass control to the thread, the pthread_join call is required.

2 Comments

@ Roney Michael:Thanks for the links. It seem I still have yet to learn the Basic C Programming 101.
I wanted to upvote the 2 answers above which are very very helpful to me, but I still have no reputation to do so, I'm sorry. I'll upvote it later after I got enough reputation. ;)

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.