Счетчик веб-страницы, где значение счетчика меньше количества посещений - PullRequest
0 голосов
/ 04 мая 2018

Ниже приведена программа, написанная для имитации основного счетчика веб-страниц. «cnt» содержит значение счетчика, и программа повторяется 100 раз, чтобы имитировать 100 посещений страницы.

#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);

}

Таким образом, код выдает некоторую информацию, как показано ниже (с «cnt» - это количество посетителей «сайта», а с повторением - «100 случайных посещений сайта».

Это системная инженерия и многопоточная проблема.

По сути, я хотел бы знать, почему результат составляет примерно 60, а не 100 (или приблизительно), а также как я мог бы внести изменения, чтобы заставить код работать более точно и согласованно, чем значение, которое я получаю.

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 Ответ

0 голосов
/ 04 мая 2018

Вы получаете меньшие значения из-за гонок данных : два потока могут считывать одно и то же значение cnt, и оба обновляют его до cnt+1 вместо ctn+1 и 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

Вам необходимо принять меры против этой гонки данных, используя семафоры , мьютекс , барьеры памяти , элементарные функции и т. Д.

...