Семафор Проблемы, а не Ожидание - PullRequest
0 голосов
/ 06 ноября 2011

У меня есть одна проблема с семафорами, хотя вы могли бы помочь мне .. Хорошо, во-первых, позвольте мне показать, что я делаю. Мне нужно c программами, одним сервером и другим именованным клиентом.

На сервере я делаю это:

#ifdef _SEM_SEMUN_UNDEFINED    //here I define semun, in case that is not defined
#undef _SEM_SEMUN_UNDEFINED
union semun {
int val;
struct semid_ds *buf;
unsigned short int *array;
struct seminfo *__buf;
};
#endif

union semun semopts;
int semID;

semID = semget(1000, 1, 0600 | IPC_CREAT | IPC_EXCL); //I want this gives error, if there is already a sem on that key
if(semID < 0){
   perror(semID);
   exit(1);
}
semopts.val = 10;
semctl(semID, 0, SETVAL, semopts);  //Here I set the val for the first sem of the group, I want it with value 10

Хорошо, это мой серверный файл, теперь на клиенте, что мне нужно сделать:

10 клиентов могут читать из памяти одновременно, поэтому для каждого читателя я делаю -1 в sem. 1 клиент может писать в память одновременно, и никто не может читать, так что в этом случае я делаю -10 в sem, верно ??

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

struct sembuf UP10 = {0, 10, 0};
struct sembuf DOWN10 = {0, -10, 0};
struct sembuf UP1 = {0, 1, 0};
struct sembuf DOWN1 = {0, -1, 0};
int semID;
semID = semget(1000, 1, 0600 | IPC_CREAT);
if(semID < 0){
  perror(semID);
  exit(1);
}

//Okay now its here on my switch where they read or write

switch(selection[0]){ //This store the number from a scanf
case '1':

semop(semID, &DOWN1, 1);
functionToRead(..);
semop(semID, &UP1, 1);
break;

case '2': //Here the client also read from memory

semop(semID, &DOWN1, 1);
functionToReadAlsoMemory(...);
semop(semID, &UP1, 1);
break;

case '3': //Here is the block where the client WRITES on memory so use the struct DOWN10 and UP10

semop(semID, &DOWN10, 1);
functionToWriteOnMemory(...);
semop(semID, &UP10, 1);
break;

}

Хорошо, проблема в том:

когда я нажимаю 3 (блок для записи в память), программа выполняет -10 по sem и вводит для этой функции, есть scanf, поэтому у sem будет 0, пока он не выйдет из функции .. когда пользователь нажимает enter и проходит через сканф. В этом случае, если на клиенте пишет, и я пытаюсь открыть другого клиента и писать, он продолжает ждать, пока другой клиент покинет функцию и выполнит sem UP10. Хорошо, это хорошо, это то, что я хочу, и затем клиент, который ждал, проходит через эту функцию, чтобы написать .. Хорошо, хорошо

Но если один клиент работает с этой функцией (этот клиент выполнял DOWN10, то есть sem 0), и я пытаюсь читать из памяти (в случае «1» или в случае «2»), он В действительности может! Но не должен !! Потому что, если sem все еще на 0, он не может сделать sem DOWN1, верно ??

Полагаю, вы, ребята, поняли мою проблему здесь, у меня есть включения для sem и тому подобное, проблема не в этом, верно? потому что это работает для 2 клиентов, пытающихся написать ..

Было бы здорово, если бы вы, ребята, поняли, где моя проблема: s Большое спасибо заранее, ура !!

1 Ответ

0 голосов
/ 06 ноября 2011

Семафоры - сложный инструмент, который слишком низкоуровневый для обычного пользовательского кода. Попробуйте вместо этого использовать управляющие структуры POSIX pthread_mutex_t и pthread_cond_t. В настоящее время их легко можно использовать в общей памяти между процессами.

Одна из основных проблем с семафорами заключается в том, что вызовы могут быть прерваны любым сигналом, в частности, если IO доставлен вашему процессу. Вам нужно будет зафиксировать возвращаемое значение и коды ошибок, которые предоставляют вызовы, а затем снова перейти в режим ожидания.

...