Trying to implement race condition using pthread
I am trying to set-up race condition to see how it happens to get an understanding. I wrote the code below. This compiles without any issue but when I run it, it does not print the count at every run. If is run it twice or thrice , then the count is printed. Is my understanding correct that in this code it is not necessary that race condition actually takes place. ( if this is correct,then I am not sure how this exits since there are no boundary condition!). Can some one give me some idea if my understanding is incorrect or the code?
Thanks.
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
void *banking(void *);
int main(){
int accounts[2]={0,0};
pthread_t tid1,tid2;
if(pthread_create(&tid1,NULL,banking,(void *)accounts))
{
perror("pthread_create");
return 1;
}
if(pthread_create(&tid2,NULL,banking,(void *)accounts))
{
perror("pthread_create");
return 1;
}
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);//program now goes into infinite loop.
return 0;
}
void *banking(void * accounts){
int *ptr=accounts;
int count=0;
do{
int temp1=ptr[0];
int temp2=ptr[1];
int amount=rand();
ptr[0]=temp1-amount;
ptr[1]=temp2+amount;
//printf("%d \n %d\n",ptr[0],ptr[1]);
count++;
}while((ptr[0]+ptr[1])==0);
printf("%d\n",count);
//return NULL;
exit(0);
}
I was trying to implement pthread_exit(NULL) to achieve the logic where the thread would exit once it do-while loop is over but as per my understanding the other running thread will not stop this way,because of which the programs goes into an infinite loop. I r开发者_JS百科ealized that exit() from any thread terminates process and incorporated exit(0) . The code works fine for some values but at random generates two different 'count' values. This happens once in 10-12 tries. Please suggest if usage of exit in a threaded function is advisable and under what situation will I have two diff values of count.
1> first correct that mistakes which "Paul R" has sauggested. then
2> you need to use pthread_join function to get succesfully completion of both thread..
here after creating both thread main process may be get over so at that time both threads are also gets over so to over come form this use othread_join for both thread in main()
add this code to end of at your main()
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
if you still not getting the funda of race condition then read belows part. which i have copied from one refrence book
Suppose that your program has a series of queued jobs that are processed by several concurrent threads.The queue of jobs is represented by a linked list of struct job objects.
After each thread finishes an operation, it checks the queue to see if an additional job is available. If job_queue is non-null, the thread removes the head of the linked list and sets job_queue to the next job on the list. The thread function that processes jobs in the queue might look like Listing 4.10. Listing 4.10 ( job-queue1.c) Thread Function to Process Jobs from the Queue
#include <malloc.h>
struct job {
/* Link field for linked list.
struct job* next;
*/
/* Other fields describing work to be done... */
};
/* A linked list of pending jobs.
struct job* job_queue;
*/
/* Process queued jobs until the queue is empty.
void* thread_function (void* arg)
{
while (job_queue != NULL) {
/* Get the next available job. */
struct job* next_job = job_queue;
/* Remove this job from the list. */
job_queue = job_queue->next;
/* Carry out the work. */
process_job (next_job);
/* Clean up. */
free (next_job);
}
return NULL;
}
*/
4.4
Synchronization and Critical Sections
Now suppose that two threads happen to finish a job at about the same time, but only one job remains in the queue.The first thread checks whether job_queue is null; find- ing that it isn’t, the thread enters the loop and stores the pointer to the job object in next_job. At this point, Linux happens to interrupt the first thread and schedules the second.The second thread also checks job_queue and finding it non-null, also assigns the same job pointer to next_job. By unfortunate coincidence, we now have two threads executing the same job.
To make matters worse, one thread will unlink the job object from the queue, leaving job_queue containing null.When the other thread evaluates job_queue->next, a segmentation fault will result.
This is an example of a race condition. Under “lucky” circumstances, this particular schedule of the two threads may never occur, and the race condition may never exhibit itself. Only under different circumstances, perhaps when running on a heavily loaded system (or on an important customer’s new multiprocessor server!) may the bug exhibit itself.
To eliminate race conditions, you need a way to make operations atomic. An atomic operation is indivisible and uninterruptible; once the operation starts, it will not be paused or interrupted until it completes, and no other operation will take place mean- while. In this particular example, you want to check job_queue; if it’s not empty, remove the first job, all as a single atomic operation.
精彩评论