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.

izza
  • 157
  • 2
  • 3
  • 13
  • OT: There is the `->` operator. – alk Mar 02 '13 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? – Code-Apprentice Mar 03 '13 at 00:29
  • Also, what is `someType`? – Code-Apprentice Mar 03 '13 at 00: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). – izza Mar 03 '13 at 00: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. – Code-Apprentice Mar 05 '13 at 01:53
  • @izza I may have misspoke. Arrays are *definitely* not a valid lvalue. They *might* be a valid rvalue in certain situations, but I don't recall for certain. – Code-Apprentice Mar 05 '13 at 01:54
  • @izza Please repost your new question about matrix assignment as a *question*. It appears that it was removed since you posted it as an *answer* instead. – Code-Apprentice Mar 05 '13 at 01:56
  • @Code-Guru: Thanks for your kind answer. I have repost a new question about matrix assignment, click here: http://stackoverflow.com/questions/15606233/shared-data-in-pthread-programming – izza Mar 25 '13 at 01:19

2 Answers2

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.

  • 1
    @ 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. – izza Mar 02 '13 at 17:28
  • 1
    @ Anthony Catel: Your suggestion work very well...!!! Thanks a lot :D. I'm going to write a matrix mult using Pthread now. – izza Mar 02 '13 at 17:34
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.
Community
  • 1
  • 1
Roney Michael
  • 3,964
  • 5
  • 30
  • 45
  • 1
    @ Roney Michael:Thanks for the links. It seem I still have yet to learn the Basic C Programming 101. – izza Mar 02 '13 at 16:56
  • 1
    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. ;) – izza Mar 02 '13 at 19:31