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.
Related
I am trying to make race condition and fix it with mutex lock. My code is working correct which is no race condition. Should not it make race condition?
#define MAX_RESOURCES 10
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
int available_resources = 10;
void* decrease_count(void count);
void increase_count(void *count);
pthread_t thread1;
pthread_t thread2;
int main () {
int decrease = 8;
int increase = 3;
pthread_create(&thread1, NULL, decrease_count, (void*) &decrease);
pthread_create(&thread2, NULL, increase_count, (void*) &increase);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
printf("amount of resource: %d",available_resources);
return 0;
}
void* decrease_count(void *count){
available_resources -= *((int *)count);
return NULL;
}
void* increase_count(void *count){
if(available_resources + *((int *)count) <= MAX_RESOURCES) {
available_resources += *((int *)count);
return 0;
}
return NULL;
}
Well, here, you are declaring in your thread function that you are going to be passed a reference to the increment/decrement value, so you can control how many counts each thread does when it runs.
The idea is to create a mutex in main, and use it in both threads to lock the resource, before doing the increment/decrement.
#define MAX_RESOURCES 10
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
int available_resources = 10;
void* decrease_count(void *count);
void* increase_count(void *count);
pthread_t thread1;
pthread_t thread2;
pthread_mutex_t the_mutex;
int main () {
int decrease = 8;
int increase = 3;
/* create the mutex before any of the threads has access to it */
int res = pthread_mutex_init(&the_mutex, NULL);
if (res < 0) {
fprintf(stderr, "pthread_create_mutex: %s\n",
strerror(errno));
}
pthread_create(&thread1, NULL, decrease_count, &decrease);
pthread_create(&thread2, NULL, increase_count, &increase);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
printf("amount of resource: %d\n",available_resources);
return 0;
}
void* decrease_count(void *_count){
int count = *(int *)_count;
int res = pthread_mutex_lock(&the_mutex);
if (res < 0) {
fprintf(stderr, "%s: mutex lock: %s\n",
__func__,
strerror(errno));
}
available_resources -= count;
res = pthread_mutex_unlock(&the_mutex);
if (res < 0) {
fprintf(stderr, "%s: mutex unlock: %s\n",
__func__,
strerror(errno));
}
return NULL;
}
void* increase_count(void *_count){
int count = *(int *)_count;
int res = pthread_mutex_lock(&the_mutex);
int overflow = 0;
if (res < 0) {
fprintf(stderr,
"%s: mutex lock: %s\n",
__func__,
strerror(errno));
}
if(available_resources + count <= MAX_RESOURCES) {
overflow = 1;
available_resources += count;
}
res = pthread_mutex_unlock(&the_mutex);
if (res < 0) {
fprintf(stderr, "%s: mutex unlock: %s\n",
__func__,
strerror(errno));
}
if (overflow) {
printf("got over the top(%d resources)\n",
MAX_RESOURCES);
}
return NULL;
}
When I use mutex_lock inside loop, my code spends huge time in execution, and I can't get the output.
I know lock () take time, but not as this!
I have this code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int x = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void *fnC()
{
int i;
for (i = 0; i < 2; i++)
{
pthread_mutex_lock(&mutex);
x++;
}
printf(" %d", x);
pthread_mutex_unlock(&mutex);
}
int main()
{
int rt1, rt2;
pthread_t t1, t2;
/* Create two threads */
if ((rt1 = pthread_create(&t1, NULL, &fnC, NULL)))
printf("Thread creation failed: %d\n", rt1);
if ((rt2 = pthread_create(&t2, NULL, &fnC, NULL)))
printf("Thread creation failed: %d\n", rt2);
/* Wait for both threads to finish */
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("\n");
return 0;
}
Anyone can explain this?
I'm trying to use semaphores to avoid that a global variable is changed by threads and this variable is supposed to increment within the for loop. My main objective is to protect the variable cnt from the threads so it can increment within the for loop. However, I don't know how to do it because this is the first time I work with semaphores.
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
sem_t semaphore;
int cnt = 0; //global shared variable
void *threadProd(void *param); //threads call this function.
int main(int argc, char *argv[])
{
int niters;
pthread_t tid1, tid2; //thread ids
sem_init(&semaphore,0,1);
if (argc != 2){
printf("Usage: %s <niters>\n", argv[0]);
exit(0);
}
niters = atoi(argv[1]);
pthread_create(&tid1, NULL, threadProd, &niters);
pthread_create(&tid2, NULL, threadProd, &niters);
pthread_join(tid1, NULL); //wait for thread to finish
pthread_join(tid2, NULL);
//check answer:
if(cnt != (2 * niters))
printf("Incorrect answer, cnt = %d\n", cnt);
else
printf("Correct answer, cnt = %d\n", cnt);
sem_destroy(&semaphore);
exit(0);
}
//Thread routine
void *threadProd(void *vargp)
{
sem_wait(&semaphore);
int upper = *((int *) vargp);
for (int i = 0; i < upper; i++)
cnt ++;
sem_post(&semaphore);
return NULL;
}
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
I have a program which consists of multiple threads.
These threads have to synchronize at some point, continue together, do their work of different lengths and then synchronize again.
Here's the example of what I mean:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#define NUM_THREADS 10
void* thread(void* idp);
int threads_running = 0;
pthread_mutex_t* mutex;
pthread_cond_t* cond;
int main(int args, char **argv)
{
pthread_mutex_t mutex_var;
pthread_cond_t cond_var;
mutex = &mutex_var;
cond = &cond_var;
pthread_mutex_init(mutex, NULL);
pthread_cond_init(cond, NULL);
pthread_t threads[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++)
{
printf("Creating Thread %d....\n", i);
int* id = malloc(sizeof(int));
*id = i;
if(0 != pthread_create(&threads[i], NULL, thread, (void *) id))
{
perror("Error while creating the threads");
exit(1);
}
}
for (int i = 0; i < NUM_THREADS; i++)
{
pthread_join(threads[i], NULL);
}
return 0;
}
void* thread(void* idp)
{
int* id = (int*) idp;
while (1)
{
sleep(*id+2); // Thread work
pthread_mutex_lock(mutex);
threads_running++;
pthread_mutex_unlock(mutex);
pthread_cond_broadcast(cond);
printf("Thread %d WAIT\n", *id);
fflush(stdout);
// Let threads synchronize
pthread_mutex_lock(mutex);
while(threads_running != NUM_THREADS)
{
pthread_cond_wait(cond, mutex);
}
pthread_mutex_unlock(mutex);
printf("Thread %d WAKEUP\n", *id);
fflush(stdout);
// and continue
pthread_mutex_lock(mutex);
threads_running--;
pthread_mutex_unlock(mutex);
}
}
The thing that happens, is that some (usually #9 and one or two others) reach Thread %d WAKEUP but before the others can wake-up threads_running is already smaller than NUM_THREADS.
How can I synchronize multiple threads, so they continue together?
I am having some trouble wrapping my head around the parallel accesses to variables.
I found the answer seconds later:
Change while(threads_running != NUM_THREADS) to while(threads_running != 0 && threads_running != NUM_THREADS)
Change threads_running--; to threads_running = 0;
Now it works perfectly.
I recommend using pthread_cond_signal() than pthread_cond_broadcast(cond);
So the code flow where while loop is exiting looks like below.
pthread_mutex_lock(mutex);
while(threads_running != 0 && threads_running != NUM_THREADS)
{
pthread_cond_wait(cond, mutex);
}
pthread_cond_signal(cond);
So the final code looks like this:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#define NUM_THREADS 10
void* thread(void* idp);
int threads_running = 0;
pthread_mutex_t* mutex;
pthread_cond_t* cond;
int main(int args, char **argv)
{
pthread_mutex_t mutex_var;
pthread_cond_t cond_var;
mutex = &mutex_var;
cond = &cond_var;
pthread_mutex_init(mutex, NULL);
pthread_cond_init(cond, NULL);
pthread_t threads[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++)
{
printf("Creating Thread %d....\n", i);
int* id = malloc(sizeof(int));
*id = i;
if(0 != pthread_create(&threads[i], NULL, thread, (void *) id))
{
perror("Error while creating the threads");
exit(1);
}
}
for (int i = 0; i < NUM_THREADS; i++)
{
pthread_join(threads[i], NULL);
}
return 0;
}
void* thread(void* idp)
{
int* id = (int*) idp;
while (1)
{
sleep(*id+2); // Thread work
pthread_mutex_lock(mutex);
threads_running++;
pthread_mutex_unlock(mutex);
printf("Thread %d WAIT\n", *id);
fflush(stdout);
// Let threads synchronize
pthread_mutex_lock(mutex);
while(threads_running != 0 && threads_running != NUM_THREADS)
{
pthread_cond_wait(cond, mutex);
}
pthread_cond_signal(cond);
pthread_mutex_unlock(mutex);
printf("Thread %d WAKEUP\n", *id);
fflush(stdout);
// and continue
pthread_mutex_lock(mutex);
threads_running = 0;
pthread_mutex_unlock(mutex);
}
}