c - thread synchronization for two threads using one semaphore -
i want synchronize threads print 1 20 odd numbers printed thread1 , numbers printed thread2
i achieved 2 semaphores.
questions:
1) can achieved using 1 semaphore ?
2) there efficient way achieve ?
if possible please provide example too.
sem_t bin_sem1, bin_sem2; int count = 1; int main() { int ret; pthread_t a_thread, b_thread; ret = sem_init(&bin_sem1, 0, 1); if (ret != 0) { perror("semaphore1 initialization failed\n"); exit(exit_failure); } ret = sem_init(&bin_sem2, 0, 0); if (ret != 0) { perror("semaphore2 initialization failed\n"); exit(exit_failure); } ret = pthread_create(&a_thread, null, thread_fun1, null); if (ret != 0) { perror("thread1 creation failed"); exit(exit_failure); } ret = pthread_create(&b_thread, null, thread_fun2, null); if (ret != 0) { perror("thread2 creation failed"); exit(exit_failure); } printf("waiting threads finish\n"); ret = pthread_join(a_thread, null); if (ret != 0) { perror("thread1 join failed"); exit(exit_failure); } printf("thread1 joined"); ret = pthread_join(b_thread, null); if (ret != 0) { perror("thread2 join failed"); exit(exit_failure); } printf("thread2 joined"); exit(exit_success); } void *thread_fun1(void *arg) { int val=0, val2=0; while (count < 20) { sem_wait(&bin_sem1); sem_getvalue(&bin_sem1, &val);sem_getvalue(&bin_sem2, &val2); printf("t 1 : after wait : sem 1 = %d, sem 2 = %d\n", val, val2); printf("t 1 : count = %d\n", count++); sem_post(&bin_sem2); sem_getvalue(&bin_sem1, &val);sem_getvalue(&bin_sem2, &val2); printf("t 1 : after post : sem 1 = %d, sem 2 = %d\n", val, val2); } pthread_exit(null); } void *thread_fun2(void *arg) { int val=0, val2=0; while (count < 20) { sem_wait(&bin_sem2); sem_getvalue(&bin_sem1, &val);sem_getvalue(&bin_sem2, &val2); printf("\t\t\t\t\t\tt 2 : after wait : sem 1 = %d, sem 2 = %d\n", val, val2); printf("\t\t\t\t\t\tt 2 : count = %d\n", count++); sem_post(&bin_sem1); sem_getvalue(&bin_sem1, &val);sem_getvalue(&bin_sem2, &val2); printf("\t\t\t\t\t\tt 2 : after post : sem 1 = %d, sem 2 = %d\n", val, val2); } pthread_exit(null); }
well, is possible use 1 semaphore in sort of hacky way. instead of using semaphore mutex, use store actual value , print numbers in thread 2 , odd numbers in thread 1. here example instead of printing 1 20, prints 20 1 can modified if required.
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> void *a_func(void *arg) { sem_t *mysem = (sem_t *) arg; int value = 20; while (value > 0) { if (value % 2 == 1) { printf("thread 1 : %d\n", value); sem_wait(mysem); } sem_getvalue(mysem, &value); } } void *b_func(void *arg) { sem_t *mysem = (sem_t *) arg; int value = 20; while (value > 0) { if (value % 2 == 0) { printf("thread 2 : %d\n", value); sem_wait(mysem); } sem_getvalue(mysem, &value); } } int main() { sem_t mysem; pthread_t a_thread, b_thread; if (sem_init(&mysem, 0, 20)) { // handle error } if (pthread_create(&a_thread, null, a_func, &mysem)) { // handle error } if (pthread_create(&b_thread, null, b_func, &mysem)) { // handle error } // wait threads finish pthread_join(a_thread, null); pthread_join(b_thread, null); }
however, semaphores used in manner , therefore suggest using atomic types instead more modern , perfect usecase. here quick example:
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <stdatomic.h> void *a_func(void *arg) { atomic_int *myint = (atomic_int *) arg; int value = 20; while (value > 0) { if (value % 2 == 1) { //printf("thread 1 : %d\n", value); value = atomic_fetch_sub(myint, 1) + 1; continue; } value = atomic_load(myint); } } void *b_func(void *arg) { atomic_int *myint = (atomic_int *) arg; int value = 20; while (value > 0) { if (value % 2 == 0) { //printf("thread 2 : %d\n", value); value = atomic_fetch_sub(myint, 1) + 1; continue; } value = atomic_load(myint); } } int main() { atomic_int myint = atomic_var_init(20); // set myint 20 pthread_t a_thread, b_thread; if (pthread_create(&a_thread, null, a_func, &myint)) { // handle error } if (pthread_create(&b_thread, null, b_func, &myint)) { // handle error } // wait threads finish pthread_join(a_thread, null); pthread_join(b_thread, null); }
as performance both single semaphore program , atomic type based program runs faster code provided. however, on scale use numbers in range of 1-20 perforamnce differences negligible.
Comments
Post a Comment