1

So below is a program written so as to mimic a basic webpage counter. 'cnt' holds the counter value and the program is repeated 100 times to mimic 100 visits to the page.

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

// repeat 100 times to mimic 100 random visits to the page
#define RPT 100

//web page visit counter
int cnt=0;

void* counter() {
   int cntLocalCopy;
   float r;
   cntLocalCopy = cnt;

   // mimicking the work of the sever in serving the page to
   // the browser
   r = rand() % 2000; 
   usleep(r);
   cnt = cntLocalCopy + 1;

} 

int main () {
   int i;
   float r;
   pthread_t tid[RPT];
   // seed the random number sequence 
   srand(time(NULL));

   for (i=0; i<RPT; i++) {

      // mimicking the random access to the web page 
      r = rand() % 2000; 
      usleep(r);

      // a thread to respond to a connection request
      pthread_create (&tid[i], NULL, &counter, NULL);

}

// Wait till threads complete. 

for (i=0; i<RPT; i++) {
   pthread_join(tid[i], NULL);}
   // print out the counter value and the number of mimicked visits
   // the 2 values should be the same if the program is written
   // properly
   printf ("cnt=%d, repeat=%d\n", cnt, RPT);

}

So the code produced some output as per below (with 'cnt' being the number of visitors to 'the website' and repeat being '100 random visits to the site'.

This is a Systems Engineering and multithreaded problem.

Basically I would like to know why the output is roughly 60 and not 100 (or approximetly) and also how I could go about making the changes to make the code run more accurately and conistently than the value sthat I am getting.

cnt=63, repeat=100
cnt=59, repeat=100
cnt=58, repeat=100
cnt=63, repeat=100
cnt=59, repeat=100
cnt=59, repeat=100

1 Answers1

1

You get smaller values due to data races: two threads may read the same value of cnt and both update it to cnt+1 instead of ctn+1and cnt+2:

Thread 1               |    Thread 2             | Comment
-----------------------+-------------------------+--------------------
cntLocalCopy = cnt;    |                         | cntLocalCopy <- 0
usleep(r);             |
                       | cntLocalCopy = cnt;     | cntLocalCopy <- 0
                       | usleep(r);
cnt = cntLocalCopy + 1;|                         | cnt <- 1
                       | cnt = cntLocalCopy + 1; | cnt <- 1

You need to take action against those data race, with semaphores, mutex, memory barriers, atomic functions, etc.

YSC
  • 38,212
  • 9
  • 96
  • 149
  • So basically there are two threads and they are both accessing and manipulating the value 'cnt'. And that is what is called a Race Condition? (Or data race)... Then the program finishing all the loops before this 'cnt' value can get to 100? How would I go about writing a program that fixes that issue? – Ibo Cetinkaya May 04 '18 at 13:13
  • @IboCetinkaya You need to take a good book or tutorial on multithreading programming. SO is not the place for that kind of question (see [help/on-topic]). The solution I suggest might be a good start, but you seriously need to learn more about it. Good luck. – YSC May 04 '18 at 13:14
  • Thanks for your help @YSC – Ibo Cetinkaya May 04 '18 at 13:18