I'm starting to learn about Multi-threaded Programming with C on Linux. Below are my exercise and my code for executing the hello function for each thread. Please show me what is wrong.
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>
#define NUM_THREADS 4
void *hello(void * );
int main() {
int j;
pthread_t tid[NUM_THREADS];
printf("My process ID %d\n", getpid());
for (j = 0; j < NUM_THREADS; j )
pthread_create(&tid[j], NULL, hello, (void*)j); //original is pthread_create([1])
for (int i = 0; i < NUM_THREADS; i )
pthread_join(tid[i], NULL); //original is pthread_join([2])
return 0;
}
void *hello(void * my_id) {
printf("Hello World from branch thread %d\n", *(int * ) my_id);
}
There are only two lines that can go wrong as below because it's a fill-in blank exercise, and the below two lines are I add. I think it's (void*)j
pthread_create(&tid[j], NULL, hello, (void*)j); //[1]
pthread_join(tid[i], NULL); //[2]
[1] is creating child thread with tid, each child thread executes hello function with argument j.
[2] is main thread only ends when all child thread is ended
I don't have the expected output for this. But I have an expected output for the advanced request (which need to change some part of the original code, not only fill in [1] and [2]) as below:
My process ID 127
Hello World from branch thread 0
Hello World from branch thread 1
Hello World from branch thread 2
Hello World from branch thread 3
My error is:
quang@quang-VirtualBox:~$ gcc exe2_1.c -o exe2_1 -pthread
exe2_1.c: In function ‘main’:
exe2_1.c:32:42: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
32 | pthread_create(&tid[j], NULL, hello, (void*)j)
Please understand that my first subject was Python, this is my second subject (operating system), I have zero knowledge of C, but my school force me to learn this. I just need the fixed code so that I can submit.
CodePudding user response:
You do not specify which output is expected. The solution would depend on the fact whether you expect to see the different number from each thread or if some threads may print the same number.
To fix the message from your compiler, you must provide a real pointer. Not just some integer that you cast to pointer.
If you do
int j = 1;
pthread_create(&tid[j], NULL, hello, (void*)j);
this will result in hello
being called with 1
which contains an integer value. But hello
thinks, it is a pointer and tries to dereference it.
This will not work.
Instead you must provide the address of some int
variable.
Changing the relevant line to
pthread_create(&tid[j], NULL, hello, &j);
would do the trick.
But... (as you commented in the meantime)
You noticed that all threads print the same number if you do this. That happens because you pass the same address of same variable to each thread. And there is no specific order when the threads are executed. Chances are good that the first thread is executed after the whole loop was done. To avoid this, you must provide each thread with a different value. You cannot do this by just adding parameters to that function call. Instead you must provide separate memory for each thread. You could do this as follows:
int params[NUM_THREADS];
for (j = 0; j < NUM_THREADS; j )
{
params[j] = j;
pthread_create(&tid[j], NULL, hello, ¶ms[j]);
}
This will cause each thread to print a different number.
CodePudding user response:
Very simple you have over complicated the passing of the parameter j you just need to pass its address using the &
Syntax is
int pthread_create(pthread_t *thread, pthread_attr_t *attr,
void *(*start_routine) (void *arg), void *arg);
Passing to a function
void *thread(void *arg)
Your line should read
pthread_create(&tid[j], NULL, hello, &j);
Output expected for your exercise
Hello World from branch thread 1
Hello World from branch thread 2
Hello World from branch thread 3
Hello World from branch thread 4