Still confused about Pthreads - c

I am using an old exam as a study guide and one of the questions is to use pthreads to fill in the following code:
#include <pthread.h>
#include <stdio.h>
typedef struct {
int a;
int b;
} local_data;
void *foo(void *arg);
int main() {
int a = 12;
int b = 9;
pthread_t tid;
pthread_attr_t attr;
local_data local;
local.a = a;
local.b = b;
pthread_attr_init(&attr);
/* block of code we are supposed to fill in (my attempt at filling it in)
pthread_create(&tid, &attr, foo, &local);
pthread_join(tid, NULL);
*/
b = b - 5;
printf("program exit. a = %d, b = %d\n", a, b);
return 0;
}
void *foo(void *arg) {
int a, b;
local_data *local = (local_data*)arg;
/* block of code we are supposed to fill in (my attempt at filling it in)
a = local->a;
b = local->b;
a++;
*/
printf("program exit. a = %d, b = %d\n", a, b);
pthread_exit(0);
}
What we are supposed to do is make our pthreads mimic this code:
int main() {
int a = 12;
int b = 9;
int fid = fork();
if (fid == 0) {
a++;
}
else {
wait(NULL);
b = b - 5;
}
printf("program exit. a = %d, b = %d\n", a, b);
return 0;
}
I've been really lost on this section and I am sure I do not understand it as well as I should (or at all). Would appreciate any answers to help me grasp the concept.

This line is wrong:
pthread_create(&tid, &attr, foo(local), NULL);
pthread_create's signature is:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void*), void *arg);
The third argument is a function and the last argument is it's argument, so instead of calling the function (foo(local)), pass the function and the argument separately:
pthread_create(&tid, &attr, foo, &local);

Related

What am I getting wrong in this Busy Waiting solution using Strict Alteration with C and Posix threads?

I am supposed to reproduce the Strict Alternation algorithm using C and Posix Threads.
I coded the below solution but the printfs aren't being outputed at all. Sometimes just the my_id is outputed but that's all. What am I doing or understanding wrong?
For example, this was the output of one of the times I ran this code:
Oher output:
Here is the code I did:
#include <pthread.h>
#include <stdio.h>
int count = 0;
int turn = 1;
struct arg_struct {
int my_id;
int other;
};
void *runner(void *param) {
struct arg_struct *args = (struct arg_struct *)param;
int my_id = args -> my_id;
int other = args -> other;
printf("my_id %d\n", my_id);
printf("other %d\n", other);
printf("Running p_thread %d\n", my_id);
while(1) {
while (turn != my_id) { }
// critical section
count = count + my_id;
printf("Critical section of p_thread %d, count was incremented by %d and is now %d\n", my_id, my_id, count);
turn = other;
// not critical section
printf("Not critical section of p_thread %d\n", my_id);
}
pthread_exit(NULL);
}
int main(int argc, char *argv[]) {
int thr_id1, thr_id2;
pthread_t p_thread1;
pthread_t p_thread2;
struct arg_struct args_p_thread1;
args_p_thread1.my_id = 1;
args_p_thread1.other = 2;
struct arg_struct args_p_thread2;
args_p_thread2.my_id = 2;
args_p_thread2.other = 1;
thr_id1 = pthread_create(&p_thread1, NULL, runner, (void*)&args_p_thread1);
thr_id2 = pthread_create(&p_thread2, NULL, runner, (void*)&args_p_thread2);
return 0;
}
The variable you use for your parameters is reused between the threads.
Your global variables are not immediately suitable for sharing between threads, so it’s possible they do not see a new value of turn and get stuck in your inner while loop.
Your main loop exits without waiting for the threads, so they may not get a chance to do much. Your program will exit at the end of the main thread, it will not automatically wait for your other threads.
This code works for me on Repl.it.
I added volatile and pthread_join
#include <pthread.h>
#include <stdio.h>
int count = 0;
volatile int turn = 1;
struct arg_struct {
int my_id;
int other;
};
void *runner(void *param) {
struct arg_struct *args = (struct arg_struct *)param;
int my_id = args -> my_id;
int other = args -> other;
printf("my_id %d\n", my_id);
printf("other %d\n", other);
printf("Running p_thread %d\n", my_id);
while(1) {
while (turn != my_id) { }
// critical section
count = count + my_id;
printf("Critical section of p_thread %d, count was incremented by %d and is now %d\n", my_id, my_id, count);
turn = other;
// not critical section
printf("Not critical section of p_thread %d\n", my_id);
}
pthread_exit(NULL);
}
int main(int argc, char *argv[]) {
int thr_id1, thr_id2;
pthread_t p_thread1;
pthread_t p_thread2;
struct arg_struct args_p_thread1;
args_p_thread1.my_id = 1;
args_p_thread1.other = 2;
struct arg_struct args_p_thread2;
args_p_thread2.my_id = 2;
args_p_thread2.other = 1;
thr_id1 = pthread_create(&p_thread1, NULL, runner, (void*)&args_p_thread1);
thr_id2 = pthread_create(&p_thread2, NULL, runner, (void*)&args_p_thread2);
int join = 0;
pthread_join(&p_thread1, &join);
pthread_join(&p_thread2, &join);
return 0;
}

UNIX Pthreads & mutex; program locks up

Following scenario:
We are supposed to make x Threads maximum. Our main-function is supposed to make a single new thread with a pointer to the function 'makeThreads'. This function is supposed to make up to 2 threads, depending on how many threads are already there. Race conditions are to avoid.
I'm stuck. I'm not exactly sure how to solve the problem I'm running into, partly because I don't can't identify the problem itself.
Suggestions are greatly appreciated!
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#define MAX_THR 20
pthread_mutex_t mutex;
int threadCount = 0;
int randomNbr(){
int number = (rand() % 10) + 1;
return number;
}
void *makeThreads(void* number){
int rndnmb = *((int *) number);
pthread_mutex_lock(&mutex);
sleep(rndnmb);
pthread_t threadDummy;
int thread1, i, threadID, rndnbr;
threadID = threadCount;
printf("Hello from Thread %d!\n", threadID);
for(i = 0; i < 2; i++){
if(threadCount < MAX_THR){
rndnbr = randomNbr();
int *rnd = &rndnbr;
threadCount++;
thread1 = pthread_create(&threadDummy, NULL, *makeThreads, (void *) rnd);
pthread_join(threadDummy, NULL);
}
}
pthread_mutex_unlock(&mutex);
printf("Goodbye from Thread %d!\n", threadID);
}
int main(){
int t1, rndnbr;
pthread_t threadOne;
pthread_mutex_init(&mutex, NULL);
srand(time(NULL));
rndnbr = randomNbr();
int *rnd = &rndnbr;
threadCount++;
t1 = pthread_create(&threadOne, NULL, *makeThreads, (void *) rnd);
pthread_join(threadOne, NULL);
}

array and vector multiplication using threads c language

I'm writing a program that uses threads to compute the production of an array by a one dimensional array, all dimensions equal "n".
Each thread must compute the production of a row of the array with that one dimensional array.
The output i'm getting seems to have got addresses values instead of the values i already entered as the matrix elements.
What am i doing wrong?
here's the code i wrote:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define mat_dim 5
static struct param
{
int mat[mat_dim][mat_dim];
int vec[mat_dim];
int ind;
int alter[mat_dim];
};
void *Calculate_row(struct param tid)
{
int i;
for (i=0; i<5; i++) {
tid.alter[tid.ind] = tid.alter[tid.ind]+tid.mat[tid.ind][i]*tid.vec[i];
}
pthread_exit((void *)&tid);
}
int main (int argc, char *argv[])
{
pthread_t thread[mat_dim];
pthread_attr_t attr;
int rc;
long t;
void *status;
int th_array[5][5]={{1,4,3,5,1},{4,6,2,8,5},{3,5,1,3,6},{1,5,6,2,8},{4,7,5,3,6}};
int th_vec[5]={1,2,1,2,1};
struct param thread_parameter;
thread_parameter.mat[5][5]=th_array;
thread_parameter.vec[5]=th_vec;
int tmp[5]={0,0,0,0,0};
thread_parameter.alter[5]=tmp;
/* Initialize and set thread detached attribute */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
for(t=0; t<mat_dim; t++) {
printf("Main: creating thread %ld\n", t);
thread_parameter.ind=t;
rc = pthread_create(&thread[t], &attr, Calculate_row,&thread_parameter);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Free attribute and wait for the other threads */
pthread_attr_destroy(&attr);
printf("the result vector is : ");
for(t=0; t<mat_dim; t++) {
rc = pthread_join(thread[t], NULL);
if (rc) {
printf("ERROR; return code from pthread_join() is %d\n", rc);
exit(-1);
}
printf("%d, ",thread_parameter.alter[t]);
}
printf("Main: program completed. Exiting.\n");
pthread_exit(NULL);
}
you are calling rc = pthread_create(&thread[t], &attr, Calculate_row,&thread_parameter);
where
struct param thread_parameter;
and the function is void *Calculate_row(struct param tid)
it should be void *Calculate_row(struct param *tid)
as a pointer is passed and change all . to ->.
All these lines:
thread_parameter.mat[5][5]=th_array;
thread_parameter.vec[5]=th_vec;
thread_parameter.alter[5]=tmp;
are wrong. The array indexes go from 0 to 4, therefore by addressing the 5th element you're out of their bounds.
You're using pthread_create the wrong way. This is the prototype:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
Your Calculate_row receives a void* as a parameter, which needs to be cast to a (struct param *) and then dereferenced.

Seg fault (core dumped) after pthread_join in C

I keep getting a seg fault (core dump) after pthread_join in my program. It prints out the expected result just fine, but seg faults when joining the thread. I have looked at several other discussions on this topic, but none of the suggested solutions seem to work in my case. Here is what my compile command looks like (no compile warnings or errors):
$ gcc -Wall -pthread test.c -o test
Here is the output:
$ ./test
1 2 3 4 5 6 7 8 9 10
Segmentation fault (core dumped)
And here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int array[10];
void *fillArray(int *size) {
int i;
for (i = 0; i < *size; i++) {
array[i] = i+1;
}
return NULL;
}
int main (int argc, char *argv[])
{
int i, rc;
int size = 10;
pthread_t thread;
void *res, *end;
//initialize the array
for (i = 0; i < size; i++) {
array[i] = 0;
}
rc = pthread_create(&thread, NULL, fillArray(&size), &res);
if (rc != 0) {
perror("Cannot create thread");
exit(EXIT_FAILURE);
}
//print the array
for (i = 0; i < size; i++) {
if (array[i] != -1)
printf("%d ", array[i]);
}
printf("\n");
rc = pthread_join(thread, &end);
if (rc != 0) {
perror("Cannot join thread");
exit(EXIT_FAILURE);
}
return 0;
}
Any ideas what could be the cause?
This doesn't compile for me: It fails with
dummy.cpp: In function ‘int main(int, char**)’:
dummy.cpp:29: error: invalid conversion from ‘void*’ to ‘void* (*)(void*)’
dummy.cpp:29: error: initializing argument 3 of ‘int pthread_create(_opaque_pthread_t**, const pthread_attr_t*, void* (*)(void*), void*)’
Which is because you're actually calling fillArray and passing its result to pthread_create, rather than passing the function pointer. I expect your code will need to look more like this (UNTESTED!) : (Note I changed signature of fillArray, created data struct type to pass to fillArray, changed how pthread_create is called)
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int array[10];
struct fillArrayData {
int * array;
int size;
int * result;
};
void *fillArray(void *void_data) {
fillArrayData * data = (fillArray*)void_data;
for (int i = 0; i < data.size; i++) {
data.array[i] = i+1;
}
//You could fill in some return info into data.result here if you wanted.
return NULL;
}
int main (int argc, char *argv[])
{
int i, rc;
int size = 10;
pthread_t thread;
void *res, *end;
//initialize the array
for (i = 0; i < size; i++) {
array[i] = 0;
}
fillArrayData data;
data.array = array;
data.size = 10;
rc = pthread_create(&thread, NULL, fillArray, &data);
if (rc != 0) {
perror("Cannot create thread");
exit(EXIT_FAILURE);
}
//print the array
for (i = 0; i < size; i++) {
if (array[i] != -1)
printf("%d ", array[i]);
}
printf("\n");
rc = pthread_join(thread, &end);
if (rc != 0) {
perror("Cannot join thread");
exit(EXIT_FAILURE);
}
return 0;
}
Error in
Calling function pointer
passing parameter to thread handler
In pthread prototype of pthread_create below
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
1st argument - pthread_variable
2nd argument - thread attrubutes
3rd argument - thread handler(function pointer name)
4th argument - variable need to pass thread handler.
In 4th argument - if two thread want to share single variable, then create global variable, and the pass this variable when creating thread.
sample program:
#include <pthread.h>
#include <stdio.h>
#define NUM_THREADS 5
void *PrintHello(void *threadid)
{
long tid;
tid = (long)threadid;
printf("Hello World! It's me, thread #%ld!\n", tid);
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
for(t=0; t<NUM_THREADS; t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}
further details here

pthread_create not working. passing argument 3 warning

I am trying to create a thread and from what I remember this should be the right way to do it:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 5
int SharedVariable =0;
void SimpleThread(int which)
{
int num,val;
for(num=0; num<20; num++){
if(random() > RAND_MAX / 2)
usleep(10);
val = SharedVariable;
printf("*** thread %d sees value %d\n", which, val);
SharedVariable = val+1;
}
val=SharedVariable;
printf("Thread %d sees final value %d\n", which, val);
}
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
for(t=0; t< NUM_THREADS; t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, SimpleThread, (void* )t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Last thing that main() should do */
pthread_exit(NULL);
}
And the error that I'm getting is this one:
test.c: In function ‘main’: test.c:28: warning: passing argument 3 of
‘pthread_create’ from incompatible pointer type
/usr/include/pthread.h:227: note: expected ‘void * (*)(void *)’ but
argument is of type ‘void (*)(int)’
I cannot change the SimpleThread function so changing the type of the parameter is not an option even though I already tried and it didn't work either.
What am I doing wrong?
SimpleThread should be declared as
void* SimpleThread(void *args) {
}
When you pass parameters to your thread, it is best to define a struct for them, pass a pointer to that struct as void*, and cast back to the right type inside the function.
Here's a compiling and "working" version of your program, although I have to admit to not knowing exactly what it's doing. For the critics in the audience, I apologize in advance for the pthread_join loop at the end.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NUM_THREADS 5
struct my_thread_info {
long which;
};
int SharedVariable = 0;
void *SimpleThread(void *data)
{
int num, val;
struct my_thread_info *info = data;
for (num = 0; num < 20; num++) {
if (random() > RAND_MAX / 2)
usleep(10);
val = SharedVariable;
printf("*** thread %ld sees value %d\n", info->which, val);
SharedVariable = val + 1;
}
val = SharedVariable;
printf("Thread %ld sees final value %d\n", info->which, val);
free(info);
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
struct my_thread_info *info;
for (t = 0; t < NUM_THREADS; t++) {
printf("In main: creating thread %ld\n", t);
info = malloc(sizeof(struct my_thread_info));
info->which = t;
rc = pthread_create(&threads[t], NULL, SimpleThread, info);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
for (t = 0; t < NUM_THREADS; t++) {
pthread_join(threads[t], NULL);
}
}

Resources