In the below code I'm just trying to see if I would be able to insert an element into an array , from each thread. It is working as expected. But then I wonder , under what circumstances there can be a race condition here. Do I really need volatile here, or semaphores? I tried removing semaphores and volatile keywords, still it works. I want to induce and see a race condition scenario as well here. On the same lines, Can I create a node from each thread and put all nodes into a linked list? These are all imaginary scenarios..!!
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include "small_appl.h"
void * thread_func(void * arg);
int itr=0;
volatile int idx=0; //array index variable
sem_t sem1;
int arr_th[5]; //array where each thread will insert an element
int func_pointed(int a,int num_t)
{
pthread_t arr_thr[num_t];
int iter;
//create threads
for(iter=0;iter<num_t;iter++)
{
pthread_create(&arr_thr[iter],NULL,thread_func,(void *)a);
}
for (iter=0;iter<num_t;iter++)
{
pthread_join(arr_thr[iter],NULL);
}
}
int main(void)
{
int ip1=5,ip2=10,rev;
rev=sem_init(&sem1,0,0);
s_type dev_s={
.f_ptr=func_pointed,
.str="Diwakar",
.val=5
};
//initialize semaphore to 1
sem_post(&sem1);
func_aux(ip1,dev_s);
for(rev=0;rev<5;rev++)
{
printf("array : %d ",arr_th[rev]);
}
}
void * thread_func(void * arg)
{
sem_wait(&sem1);
printf("Got sema\n");
arr_th[idx]=itr;
idx++; itr++;
printf("Releasing sema\n");
sem_post(&sem1);
sleep(5);
}
To create or simulate a situation where a thread overlays the work done by another thread, then remove the semaphore and strategically place the sleep, as:
void * thread_func(void * arg)
{
//sem_wait(&sem1);
//printf("Got sema\n");
arr_th[idx]=itr;
// print arr_th[idx]
sleep(5); <<== gives the threads more of a chance to wipe-out each other
// print arr_th[idx]
idx++; itr++;
//printf("Releasing sema\n");
//sem_post(&sem1);
sleep(5);
}
You can add some printf
statements that explicitly highlight the problem.
volatile
tells the compiler to not remove a variable that is not used or at least appears to be unused.
You can update a linked list from multiple threads, but you must serialize the critical section of the code that updates the links (next and/or prev) in the list.
In windows XP and above the CRT is thread safe, so each thread can issue malloc()
, printf
and the like without having to serialize the threads around those calls.