POSIX Producer-consumer - c

I have a problem connected with producers and consumers. I have 1 producer and 3 consumers. Producer produce letters which i put in my queue, and consumers take this letters. It is considered that letter has been removed from the queue, when 2 of consumers took it, but there is an option, that consumer A and consumer C can't take the same letter(it's possible that con. A will take letter first, then con. B will take it second or con. B first, then con C(or A) second, but no possibility when A and C together).
I wrote a code solving this problem, but now I can't print enything from functions.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include "FIFO.h"
#define semaphore sem_t
#define MAX_SIZE _SIZE
#define SLEEP 1
#define true 1
FIFO buff;
semaphore full, empty, a_read, b_read, c_read, mutex;
void randSleep(int max) {
double x = rand()/(double)RAND_MAX;
usleep( (int)floor( x*max ) );
}
void* producer_func()
{
char c='A';
while(GetAmount(&buff)<MAX_SIZE)
{
sem_wait(&empty);
sem_wait(&mutex);
Push(&buff, c);
sem_post(&mutex);
sem_post(&full);
randSleep(SLEEP);
}
pthread_exit(NULL);
}
void* consumer_a_func()
{
char c;
long int first_met;
while(true)
{
sem_wait(&a_read);
sem_wait(&full);
if (sem_getvalue(&b_read,&first_met)) printf("Error with returning b_read value");
sem_wait(&mutex);
if (first_met)
{
c = First(&buff);
sem_post(&mutex);
}
else
{
c = Pop(&buff);
sem_post(&mutex);
sem_post(&a_read);
sem_post(&b_read);
sem_post(&empty);
}
//printf("c value %s\n", c);
randSleep(SLEEP);
}
pthread_exit(NULL);
}
void* consumer_b_func()
{
char c;
long int first_met_a, first_met_c ;
while(true)
{
sem_wait(&b_read);
sem_wait(&full);
if (sem_getvalue(&a_read,&first_met_a)) printf("Error with returning a_read value");
if (sem_getvalue(&c_read,&first_met_c)) printf("Error with returning c_read value");
sem_wait(&mutex);
if (first_met_a && first_met_c)
{
c = First(&buff);
sem_post(&mutex);
}
else
{
c = Pop(&buff);
sem_post(&mutex);
sem_post(&b_read);
if (first_met_a)
sem_post(&c_read);
else
sem_post(&a_read);
sem_post(&empty);
}
//printf("c value %s\n", c);
randSleep(SLEEP);
}
pthread_exit(NULL);
}
void* consumer_c_func()
{
char c;
long int first_met;
while(true)
{
sem_wait(&c_read);
sem_wait(&full);
if (sem_getvalue(&b_read,&first_met)) printf("Error with returning b_read value");
sem_wait(&mutex);
if (first_met)
{
c = First(&buff);
sem_post(&mutex);
}
else
{
c = Pop(&buff);
sem_post(&mutex);
sem_post(&c_read);
sem_post(&b_read);
sem_post(&empty);
}
printf("c value %s\n", c);
randSleep(SLEEP);
}
pthread_exit(NULL);
}
int main()
{
Init(&buff);
sem_init(&empty, 0, MAX_SIZE);
sem_init(&full, 0, 0);
sem_init(&a_read, 0, 1);
sem_init(&b_read, 0, 1);
sem_init(&c_read, 0, 1);
sem_init(&mutex, 0, 1);
pthread_t producer, consumer_a, consumer_b, consumer_c;
pthread_create(&producer, NULL, producer_func, NULL);
printf("All right\n");
pthread_create(&consumer_a, NULL, consumer_a_func, NULL);
printf("All right\n");
pthread_create(&consumer_b, NULL, consumer_b_func, NULL);
printf("All right\n");
pthread_create(&consumer_c, NULL, consumer_c_func, NULL);
printf("All right\n");
pthread_join(&producer, (void**)NULL);
pthread_join(&consumer_a, (void**)NULL);
pthread_join(&consumer_b, (void**)NULL);
pthread_join(&consumer_c, (void**)NULL);
}
files FIFO.h, FIFO.c
error looks like
In _IO_vfprintf_internal (s=0x7ffff78ac620 <_IO_2_1_stdout_>, format=, ap=ap#entry=0x7ffff6acfe58) at vfprintf.c:1632 ()
Or segmentation fault(core dumped)
But sometimes this code runs correctly, but without any printf's which i wrote in producer-consumer functions

//printf("c value %s\n", c);
c is a char, to print it you should use
printf("c value %c\n", c);
You can try to compile with -Wformat, so warning will happend if you use invalid format for variables in the printf calls.

Related

How to implement futex_wait sysccall for pid

I have a code which puts threads to sleep using futex_wait syscall. how can i put a process to sleep using futex_wait syscall?
I understand this program, it creates the thread and put them on sleep and then calls the futex_Wake syscall to wake the thread and futex_wake should return the number of threads it has woken up
Sample Code:
#include <stdio.h>
#include <pthread.h>
#include <linux/futex.h>
#include <syscall.h>
#include <unistd.h>
#define NUM 2
int futex_addr;
int futex_wait(void* addr, int val1){
return syscall(SYS_futex,&futex_addr,val1, NULL, NULL, 0);
}
int futex_wake(void* addr, int n){
int msecs = 0;
int waked = 0;
while(1){
sleep(1);
msecs++;
waked = syscall(SYS_futex, addr, FUTEX_WAKE, n, NULL, NULL, 0);
if (waked == n)
break;
if (msecs > 100){
printf("Wake timedout\n");
return 0;
}
}
return waked;
}
void* thread_f(void* par) {
int id = (int) par;
/*go to sleep*/
futex_addr = 0;
int ret = futex_wait(&futex_addr,0);
printf("Futex_wait_returned %d\n", ret);
// printf("Thread %d starting to work!\n",id);
return NULL;
}
int main () {
pthread_t threads[NUM];
int i;
for (i=0;i<NUM;i++) {
pthread_create(&threads[i],NULL,thread_f,(void *)i);
}
printf("Everyone wait...\n");
sleep(1);
printf("Now go!\n");
/*wake threads*/
int ret = futex_wake(&futex_addr, NUM);
printf("No of futex_wake processes are %d\n", ret);
/*give the threads time to complete their tasks*/
sleep(1);
printf("Main is quitting...\n");
return 0;
}
I am quite new to it, so i want to understand what changes should i make to put a process to sleep using futex

Producer consumer semaphore value is not correct

I'm trying to implement producer-consumer problem in C using processes and System V IPC and I'm stuck on one thing. This is early version of my code (without implementing queue operations or even producer and consumer executing in loop) that I was using to learn and test how semaphores work:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <errno.h>
#include <time.h>
#include "sem.h"
#include "shm.h"
#define BUFFER_SIZE 9
int full;
int empty;
int mutex;
struct buff {
int queue[BUFFER_SIZE];
} *buffer;
void producer();
void consumer();
int main() {
int parent_pid, pid, i;
parent_pid = getpid();
int shmid = allocate_shared_memory(sizeof(*buffer));
buffer = (struct buff *) attach_shared_memory(shmid);
for (i = 0; i < BUFFER_SIZE; i++) {
buffer->queue[i] = 0;
}
full = sem_allocate();
empty = sem_allocate();
mutex = sem_allocate();
printf("Full %d\n", full);
printf("Empty %d\n", empty);
printf("Mutex %d\n", mutex);
sem_init(full, 0);
sem_init(empty, BUFFER_SIZE);
sem_init(mutex, 1);
printf("Full value %d\n", sem_get_val(full));
printf("Empty value %d\n", sem_get_val(empty));
printf("Mutex value %d\n", sem_get_val(mutex));
srand(time(0));
pid = fork();
if (!pid) {
printf("Producer here: %d\n", getpid());
producer();
printf("Full value after prod() %d\n", sem_get_val(full));
return 0;
} else printf("Created new producent: %d\n", pid);
sleep(1);
pid = fork();
if (!pid) {
printf("Consumer here: %d\n", getpid());
printf("Full value before cons() %d\n", sem_get_val(full)); //here I always get 0
consumer();
return 0;
} else printf("Created new consumer: %d\n", pid);
while (1)
{
int status;
pid_t done = wait(&status);
if (done == -1)
{
if (errno == ECHILD) break; // no more child processes
}
else
{
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
exit(1);
}
}
}
if (getpid() == parent_pid) {
sem_deallocate(full);
sem_deallocate(empty);
sem_deallocate(mutex);
}
}
void producer() {
sem_wait(empty);
sem_wait(mutex);
printf("Producer is producing!\n");
buffer->queue[0]=0;
sem_post(mutex);
sem_post(full);
}
void consumer() {
sem_wait(full);
sem_wait(mutex);
printf("Consumer is consuming!\n");
sem_post(mutex);
sem_post(empty);
}
int sem_allocate() {
return semget(IPC_PRIVATE, 1, IPC_CREAT | 0666);
}
void sem_deallocate(int semid) {
if (semctl(semid, 0, IPC_RMID, NULL) == -1)
{
perror("Error releasing semaphore!\n");
exit(EXIT_FAILURE);
}
}
int sem_init(int semid, int value) {
union semun arg;
arg.val = value;
if (semctl(semid, 0, SETVAL, arg) == -1) {
perror("semctl");
return -1;
}else return 1;
}
int sem_wait(int semid) {
printf("Someone is waiting %d\n", semid);
struct sembuf sem = { 0, -1, SEM_UNDO };
return semop(semid, &sem, 1);
}
int sem_post(int semid) {
printf("Someone is posting %d\n", semid);
struct sembuf sem = { 0, 1, SEM_UNDO };
return semop(semid, &sem, 1);
}
int sem_get_val(int semid) {
return semctl(semid, 0, GETVAL, 0);
}
int allocate_shared_memory(int size) {
return shmget(IPC_PRIVATE, size, IPC_CREAT | SHM_W | SHM_R);
}
void deallocate_shared_memory(const void* addr, int shmid) {
shmctl(shmid, IPC_RMID, 0);
}
void* attach_shared_memory(int shmid) {
return shmat(shmid, NULL, 0);
}
sem.h:
#include <sys/types.h>
#include <errno.h>
union semun {
int val;
struct semid_ds *buf;
ushort* array;
};
int sem_post(int);
int sem_wait(int);
int sem_allocate();
void sem_deallocate(int);
int sem_init(int, int);
int sem_get_val(int);
shm.h:
#include <stdio.h>
#include <sys/shm.h>
#include <sys/stat.h>
int allocate_shared_memory(int size);
void deallocate_shared_memory(const void* addr, int shmid);
void* attach_shared_memory(int shmid);
Why before executing consumer function value of full semaphore is 0? Even if right after producer finishes his job the value is 1...
I'm new to this kind of topics so maybe there is an obvious explenation of the situation, but I have no idea what can I do and hope you can help me.
You initialize the "full" semaphore to zero. Your "child" producer, prior to exiting calls your sem_post() function, which calls semop() with a SEM_UNDO argument.
int sem_post(int semid) {
printf("Someone is posting %d\n", semid);
struct sembuf sem = { 0, 1, SEM_UNDO };
return semop(semid, &sem, 1);
}
The Ubuntu Linux man page for semop says the following about SEM_UNDO:
... If an operation specifies SEM_UNDO, it will be automatically
undone when the process terminates.
This means, "producer" increments "full" prior to exiting, then after it exits the system "undoes" the increment (i.e. it decrements "full") setting it back to zero.
So,for the purposes of the "full" semaphore, you should NOT specify SEM_UNDO.

Threads are created, then all exit before critical region

I need to write a program for class that creates 8 threads. 4 producer, and 4 consumer. The producers need to loop, and randomly send SIGUSR1 or SIGUSR2 to all consumer threads. Only 2 should register if they have received SIGUSR1 and the other 2 register SIGUSR2.
When I try to run it all threads are created, "prod ready" is printed by all 4 producer threads,"waiting 1" is printed by both threads, but "waiting 2" is printed 3 times then all threads exit. At the end of debugging it says that the process exits normally.
I need to use semaphores to control the critical regions. Any help would be great.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <signal.h>
#define NP 4
#define NC1 2
#define NC2 2
#define CNT 10
void handler1(int signum);
void handler2(int signum);
typedef struct {
int sent;
int received;
int buf[1];
int SIG1;
int SIG2;
sem_t con;
sem_t prod;
} sbuf_t;
sbuf_t buff;
void *producer() {
printf("prod ready \n");
int s;
while(1){
sem_wait(&buff.prod);
s=rand()%2;
if(s==1){
buff.sent++;
kill(0,SIGUSR1);
}
else if(s==2){
buff.sent++;
kill(0,SIGUSR2);
}sem_post(&buff.prod);
}
}
void *consumer1() {
signal(SIGUSR1, handler1);
printf("waiting 1\n");
while(1){
}
}
void *consumer2() {
signal(SIGUSR2, handler2);
printf("waiting 2\n");
while(1){
}
}
void handler1(int signum){
if(signum==SIGUSR1){
sem_wait(&buff.con);
printf("Caught 1\n");
buff.received++;
buff.SIG1++;
sem_post(&buff.con);
}
}
void handler2(int signum){
if(signum==SIGUSR2){
sem_wait(&buff.con);
printf("caught 2 \n");
buff.received++;
buff.SIG2++;
sem_post(&buff.con);
}
}
void main(){
pthread_t threads[9];
buff.SIG1=0;
buff.SIG2=0;
buff.sent=0;
buff.received=0;
int index;
sem_init(&buff.con, 0, 0);
sem_init(&buff.prod, 0, 0);
for (index = 0; index < NP; index++) {
pthread_create(&threads[index], NULL, producer,NULL);
}
for (index = 0;index < NC1;index++) {
pthread_create(&threads[index+4], NULL, consumer1,NULL);
}
for (index = 0;index < NC2;index++) {
pthread_create(&threads[index+6], NULL, consumer2,NULL);
}
}
In the main() function, the threads are being created,
then main() exits.
When main() exits, all the threads are also exited.
Suggest reading about such functions as: pthread_exit() and pthread_join()
Note: the following has an error in the handling of the signals and in the handling of the semaphores, but will demonstrate the use of pthread_join() and pthread_exit()
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <signal.h>
#define NP 4
#define NC1 2
#define NC2 2
#define CNT 10
#define MAX_THREADS (9)
void handler1(int signum);
void handler2(int signum);
struct sbuf_t
{
int sent;
int received;
int buf[1];
int SIG1;
int SIG2;
sem_t con1;
sem_t con2;
sem_t prod;
};
typedef struct sbuf_t myData;
myData buff;
void *producer( void *dummy )
{
(void)dummy;
printf("prod ready \n");
int s;
while(1)
{
sem_wait(&buff.prod);
s=rand()%2;
if( !s )
{
buff.sent++;
kill( 0, SIGUSR1 );
}
else // if( s )
{
buff.sent++;
kill( 0, SIGUSR2 );
}
//sem_post(&buff.prod);
}
pthread_exit( NULL );
} // end thread: producer
void *consumer1( void *dummy )
{
(void)dummy;
//signal(SIGUSR1, handler1);
printf("waiting 1\n");
while(1)
{
sem_wait( &buff.con1 );
// do something
//sem_post( &buff.prod );
}
pthread_exit( NULL );
} // end thread: consumer1
void *consumer2( void *dummy )
{
(void)dummy;
//signal(SIGUSR2, handler2);
printf("waiting 2\n");
while(1)
{
sem_wait( &buff.con2 );
// do something
//sem_post( &buff.prod );
}
pthread_exit( NULL );
} // end thread: consumer2
void handler(int signum)
{
sem_post(&buff.prod);
if(signum==SIGUSR1)
{
//sem_wait(&buff.con);
puts("Caught 1");
buff.received++;
buff.SIG1++;
sem_post(&buff.con1);
}
else if(signum==SIGUSR2)
{
//sem_wait(&buff.con);
puts("caught 2");
buff.received++;
buff.SIG2++;
sem_post(&buff.con2);
}
} // end signal handler: handler2
int main( void )
{
pthread_t threads[ MAX_THREADS ];
buff.SIG1=0;
buff.SIG2=0;
buff.sent=0;
buff.received=0;
int index;
sem_init(&buff.con1, 0, 0);
sem_init(&buff.con2, 0, 0);
sem_init(&buff.prod, 0, 0);
signal(SIGUSR2, handler);
signal(SIGUSR1, handler);
for (index = 0; index < NP; index++)
{
pthread_create(&threads[index], NULL, producer,NULL);
}
for (index = 0;index < NC1;index++)
{
pthread_create(&threads[index+4], NULL, consumer1,NULL);
}
for (index = 0;index < NC2;index++)
{
pthread_create(&threads[index+6], NULL, consumer2,NULL);
}
for( size_t x=0; x<MAX_THREADS; x++ )
{
pthread_join( threads[x], NULL );
}
} // end function: main
HOWEVER, the methods to handle signals to threads does not use kill() as that is for processes.
rather the code should use functions similar to::
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
int pthread_cond_signal(pthread_cond_t *cond)
The signaled thread should block on a pthread_cond_wait() call until another thread sends a signal using pthread_cond_signal(), with the same condition variable.
Considering the analogy with signals delivered to processes, this is a bit different because the signaled thread has already suspended its execution waiting for a signal, unlike a process that simply gets interrupted and goes on.
For you example, you are creating your producers before your consumers. Also in your producer, you are using a random number generator to determine if you issue USR1 or USR2. Your description gave the impression you wanted two of each (versus some random mix totaling 4) which is what I see the code doing for you.

get return value from 2 threads in C

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <stdint.h>
#include <inttypes.h>
typedef struct tmp_num{
int tmp_1;
int tmp_2;
}t_num;
t_num t_nums;
void *num_mezzo_1(void *num_orig);
void *num_mezzo_2(void *num_orig);
int main(int argc, char *argv[]){
pthread_t thread1, thread2;
int tmp=0,rc1,rc2,num;
num=atoi(argv[1]);
if(num <= 3){
printf("Questo è un numero primo: %d\n", num);
exit(0);
}
if( (rc1=pthread_create( &thread1, NULL, &num_mezzo_1, (void *)&num)) ){
printf("Creazione del thread fallita: %d\n", rc1);
exit(1);
}
if( (rc2=pthread_create( &thread2, NULL, &num_mezzo_2, (void *)&num)) ){
printf("Creazione del thread fallita: %d\n", rc2);
exit(1);
}
t_nums.tmp_1 = 0;
t_nums.tmp_2 = 0;
pthread_join(thread1, (void **)(&t_nums.tmp_1));
pthread_join(thread2, (void **)(&t_nums.tmp_2));
tmp=t_nums.tmp_1+t_nums.tmp_2;
printf("%d %d %d\n", tmp, t_nums.tmp_1, t_nums.tmp_2);
if(tmp>2){
printf("Questo NON è un numero primo: %d\n", num);
}
else{
printf("Questo è un numero primo: %d\n", num);
}
exit(0);
}
void *num_mezzo_1(void *num_orig){
int cont_1;
int *n_orig=(int *)num_orig;
t_nums.tmp_1 = 0;
for(cont_1=1; cont_1<=(*n_orig/2); cont_1++){
if((*n_orig % cont_1) == 0){
(t_nums.tmp_1)++;
}
}
pthread_exit((void *)(&t_nums.tmp_1));
return NULL;
}
void *num_mezzo_2(void *num_orig){
int cont_2;
int *n_orig=(int *)num_orig;
t_nums.tmp_2 = 0;
for(cont_2=((*n_orig/2)+1); cont_2<=*n_orig; cont_2++){
if((*n_orig % cont_2) == 0){
(t_nums.tmp_2)++;
}
}
pthread_exit((void *)(&t_nums.tmp_2));
return NULL;
}
How this program works: i have to input a number and this program will calculate if it is a prime number or not (i know that it is a bad algorithm but i only need to learn pthread).
The problem is that the returned values are too much big.For example if i write "12" the value of tmp tmp_1 tmp_2 into the main are 12590412 6295204 6295208.Why i got those numbers??
The problem is with your return statements:
First:
pthread_exit((void *)(&t_nums.tmp_1));
return NULL;
}
If you're going to just return and die, you don't need to call pthread_exit()
Second, you're returning an address (&), so that's what you're printing. Try this:
return ((void *)(t_nums.tmp_1));
}
Some considerations:
Remember that the return value from pthread_exit only works for JOINABLE threads. In some other situations you may use a different pthread type (detached).
In your example you were returning something like this: void pthread_exit(void **retval);
There is a sigsegv when there is no args.

Thread sync by using mutex and barrier in C

I am trying to use pthread mutex variables and barrier to synchronize the output of my program, but it is not working the way I want it to. Each thread is seeing its final value every 20 values (coming from the for loop) which is alright but I'm trying to make them all get to the same final value (if using 5 threads, all of them should see 100 as final value, with 4 threads, 80, etc)
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int SharedVariable =0;
void *SimpleThread(void *args)
{
int num,val,rc;
int which =(int)args;
rc = pthread_mutex_lock(&mutex1);
for(num=0; num<20; num++){
#ifdef PTHREAD_SYNC
if(random() > RAND_MAX / 2)
usleep(10);
#endif
//pthread_mutex_lock(&mutex1);
val = SharedVariable;
printf("*** thread %d sees value %d\n", which, val);
//pthread_mutex_lock(&mutex1);
SharedVariable = val+1;
pthread_mutex_unlock(&mutex1);
}
val=SharedVariable;
printf("Thread %d sees final value %d\n", which, val);
//pthread_mutex_destroy(&mutex1);
//pthread_exit((void*) 0);
//pthread_mutex_unlock(&mutex1);
}
int main (int argc, char *argv[])
{
if(atoi(argv[1]) > 0){
int num_threads = atoi(argv[1]);
//pthread_mutex_init(&mutex1, NULL);
pthread_t threads[num_threads];
int rc;
long t;
rc = pthread_mutex_lock(&mutex1);
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);
}
//pthread_join(thread1);
}
rc= pthread_mutex_unlock(&mutex1);
}
else{
printf("ERROR: The parameter should be a valid positive number.");
exit(-1);
}
pthread_mutex_destroy(&mutex1);
pthread_exit(NULL);
}
Any suggestions or help is greatly appreciated!
Thanks in advanced!
You need to use a barrier (pthread_barrier_wait()) before checking for the final value - this ensures that no thread will proceed until all threads have reached the barrier.
In addition, you should be calling pthread_join() to wait for the threads to finish, and you only need to hold the mutex around the increment:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_barrier_t barrier1;
int SharedVariable = 0;
void *SimpleThread(void *args)
{
int num,val;
int which = (int)args;
for(num = 0; num < 20; num++) {
#ifdef PTHREAD_SYNC
if(random() > RAND_MAX / 2)
usleep(10);
#endif
pthread_mutex_lock(&mutex1);
val = SharedVariable;
printf("*** thread %d sees value %d\n", which, val);
SharedVariable = val + 1;
pthread_mutex_unlock(&mutex1);
}
pthread_barrier_wait(&barrier1);
val = SharedVariable;
printf("Thread %d sees final value %d\n", which, val);
return 0;
}
int main (int argc, char *argv[])
{
int num_threads = argc > 1 ? atoi(argv[1]) : 0;
if (num_threads > 0) {
pthread_t threads[num_threads];
int rc;
long t;
rc = pthread_barrier_init(&barrier1, NULL, num_threads);
if (rc) {
fprintf(stderr, "pthread_barrier_init: %s\n", strerror(rc));
exit(1);
}
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);
}
}
for (t = 0; t < num_threads; t++) {
pthread_join(threads[t], NULL);
}
}
else {
printf("ERROR: The parameter should be a valid positive number.\n");
exit(-1);
}
return 0;
}
Try to move the pthread_mutext_unlock(&mutext1) out of the for loop in your SimpleThread. You lock once and unlock mutiple(20) times in your original code.
Alternatively, you could move pthread_mutex_lock(&mutext1) into the for loop, just before you read and modify your SharedVariable. In this case, each thread's add-by-one operation may not consecutive but each thread will get the correct final value.
And before you read the final value of the SharedVariable, use a barrier to wait all the threads finish their job.

Resources