Блокировка семафора не работает должным образом в проблеме - PullRequest
0 голосов
/ 29 октября 2018

У меня проблема с поставками, которая гласит:

Серверы могут быть предназначены для ограничения количества открытых соединения. Например, сервер может пожелать иметь только N сокет-соединений в любой точке во время. Как только N подключений установлено, сервер не будет принимать другие входящие соединение, пока существующее соединение не будет освобождено. Написать программу с использованием семафоров синхронизировать активность сервера, чтобы ограничить количество одновременных подключений.

Чтобы решить ее, я создал 2 семафора:

  1. семафор, который инициализирован в N.
  2. семафор для обеспечения взаимного исключения.

Я должен создать таким образом, чтобы, если все N-соединение было установлено, клиент должен был ждать, пока не будет произведено освобождение.

Я пытался закодировать его, но код работает неправильно:

 #include<stdio.h>
 #include<stdlib.h>
 #include<unistd.h>
 #include<pthread.h>
 #include<semaphore.h>
 #include<stdlib.h> 
 #include<string.h>

sem_t allow;
sem_t mutex;

void *acquire(void * arg)
{
 int tid = *(int *)arg;
 tid+=1;
 sem_wait(&mutex);

 sem_wait(&allow);                       


printf("\n Client %d is connected to the server....",tid);
sem_post(&mutex);
sleep(rand()%10);
release(tid);

}
void  release(int num)
{
  printf("\n Client %d releases the Server ....",num);
  sem_post(&allow);                       
}   
void main(int argc,char ** argv)
{
int n;
int i;
printf("\n Enter the number of client :");
scanf("%d", &n);
int maxi=3;         // maximum no. of connection available
sem_init(&allow,0,maxi);  // semaphore that is initialised to maxi. 
                           //no. of connection
sem_init(&mutex,0,1);  // for mutual exclusion

pthread_t thread[n];

for(i=0;i<n;i++) {
    pthread_create(&thread[i],NULL,acquire,&(i));   // Clients are 
                                                  // acquiring ..
}

for(i=0;i<n;i++)
    pthread_join(thread[i],NULL);

sem_destroy(&allow);
sem_destroy(&mutex);

}

Он дает другой порядок выполнения, например, даже перед установлением соединения (клиент "x"), и освобождает соединение, как ..

Выход:

Введите номер клиента: 6

Клиент 3 подключен к серверу ....

Клиент 3 подключен к серверу ....

Клиент 4 подключен к серверу ....

Клиент 3 освобождает Сервер ....

Клиент 6 подключен к серверу ....

Клиент 3 освобождает Сервер ....

Клиент 6 подключен к серверу ....

Клиент 4 освобождает Сервер ....

Клиент 1 подключен к серверу ....

Клиент 6 освобождает Сервер ....

Клиент 6 освобождает Сервер ....

Клиент 1 освобождает Сервер ....

Пожалуйста, помогите мне исправить код !!

И извините за плохой титул !!!

1 Ответ

0 голосов
/ 29 октября 2018

Наиболее вероятная проблема в том, как вы создаете тему:

pthread_create(&thread[i],NULL,acquire,&(i));

В качестве аргумента для потоков вы передаете указатель на локальную переменную i. Проблема в том, что все потоки получают один и тот же указатель , и это может означать, что несколько потоков могут разыменовать его и получить одно и то же значение!

Обычно на самом деле не следует приводить нормальные значения в качестве указателей, но в таком случае это обычно принимается. Однако не следует приводить непосредственно к указателю, а использовать стандартный фиксированный тип ширины intptr_t, а затем приводить его к указателю:

pthread_create(&thread[i],NULL,acquire,(void *) (intptr_t) i);

Затем вы выполняете противоположное приведение в функциях потока:

void *acquire(void * arg)
{
    int tid = (int) (intptr_t) arg;
    ...
}

Таким образом, у каждого потока будет свой «идентификатор».

...