2016-05-31 32 views
0

Ich habe ein Client-Server-Projekt mit Semaphoren. Ich laufe beide aus dem gleichen Ordner, und sie verwenden den gleichen Schlüssel. Nun möchte ich, dass der Server den Semaphor sperrt. Daher kann der Client keine Befehle ausführen, bis der Server ihn freigibt, aber der Client ignoriert die Sperre des Servers. Ich verstehe nicht, wo mein Fehler ist. Server-Code:zwei Semaphore nicht kommunizieren

#include<stdio.h> 
#include<string.h> 
#include<pthread.h> 
#include<stdlib.h> 
#include<unistd.h> 
#include <sys/types.h> 
#include <sys/ipc.h> 
#include <sys/sem.h> 
#include <signal.h> 
#include <sys/shm.h> 
#include <sys/stat.h> 
#define FLAGS IPC_CREAT | 0644 
union semun { 
    int val; 
    struct semid_ds *buf; 
    ushort *array; }; 
union semun semarg; 
struct sembuf sops[1]; 
int main() { 
    semarg.val=1; 
    int resultsCreator=open("results.txt",O_CREAT|O_RDWR); 
    key_t key; 
    key = ftok("results.txt", 'k'); 
    int shmid = shmget(key, 12, FLAGS); 
    int semfor = semget(key, 1, IPC_CREAT | IPC_EXCL | 0666); 
    semctl (semfor , 0 , SETVAL , semarg); 
    sops->sem_num = 0; 
    sops->sem_flg = 0; 
    sops->sem_op = -1; 
    int k = semop (semfor , sops , 1); //lock the semaphore 
    char* shmaddr; 
    int numWaiting =0; 
    while(1){ 
     sleep(2); //CHECK EVERY 2 SECONDS IF SOMEONE IS WAITING 
     numWaiting = semctl(semfor, 0, GETNCNT, semarg); 
     if(numWaiting==0){ 
      printf("none waiting\n"); 
      continue; } 
     printf("more than one waiter\n"); //NEVER GETS HERE 
    } //END WHILE 

Client-Code:

#include<stdio.h> 
#include<string.h> 
#include<pthread.h> 
#include<stdlib.h> 
#include<unistd.h> 
#include <sys/types.h> 
#include <sys/ipc.h> 
#include <sys/sem.h> 
#include <signal.h> 
#include <sys/shm.h> 
#include <sys/stat.h> 
#define FLAGS IPC_CREAT | 0644 
union semun { 
    int val; 
    struct semid_ds *buf; 
    ushort *array; 
}; 
union semun semarg; 
struct sembuf sops[1]; 
int main() 
{ 
    key_t key; 
    key = ftok("results.txt", 'k'); 
    int shmid = shmget(key, 12, FLAGS); 
    semarg.val=1; 
    int semfor = semget(key, 0, 0666); 
    semctl (semfor , 0 , SETVAL , semarg); 
    sops->sem_num = 0; 
    sops->sem_flg = 0; 
    sops->sem_op = -1; 
    semop (semfor , sops , 1); 
    printf("skipped lock\n"); //PRINTS IT, EVEN WHEN IT'S STILL LOCKED 
    sops->sem_op = 1; 
    semop (semfor , sops , 1); 
    return 0; 
} 

warum der Client die Semaphore Sperre des Servers ignorieren?

+0

Vermisst der echte Code auch eine Fehlerüberprüfung? – alk

+0

/Ich löschte einige nicht wichtige Teil, um es so kurz wie möglich zu machen, aber mein Code hat keine Fehler, ich zeigte hier genau, was es druckt –

+1

* Ich löschte einige nicht wichtige Teil * Wenn Sie nicht wissen, warum es nicht ist arbeiten, können Sie nicht wissen, welche Teile unwichtig sind. Drucken Sie den Rückgabewert von 'semget()' - jedes Mal, wenn Sie es ausführen. –

Antwort

0

Es gab eine ähnliche Frage, auf die ich kopiere ich es so beantwortet werde einfach hier über

Bei technischen sein werden, wenn Sie Aufgaben zwischen Threads sind die Synchronisierung Sie sollten Semaphore verwenden. Beispiel zum Lesen der Eingabe vor dem Parsen. Here's eine Antwort auf Semaphoren.

Wenn Sie jedoch gemeinsam genutzte Ressourcen verwenden und Race Condition/zwei Threads gleichzeitig vermeiden möchten, sollten Sie Mutexe verwenden. Here's eine Frage, was ist ein Mutex.

Schauen Sie sich auch die disambiguation von Michael Barr, die wirklich gut ist.

Ich würde beide Fragen gründlich und die Disambiguierung lesen, und Sie könnten am Ende nicht mit Semaphor und nur Mutexe, da von dem, was Sie erklärt, Sie steuern nur eine gemeinsame Ressource.

Gemeinsame Semaphore Funktion

int sem_init(sem_t *sem, int pshared, unsigned int value); //Use pshared with 0, starts the semaphore with a given value 

int sem_wait(sem_t *sem);//decreases the value of a semaphore, if it's in 0 it waits until it's increased 

int sem_post(sem_t *sem);//increases the semaphore by 1 

int sem_getvalue(sem_t *sem, int *valp);// returns in valp the value of the semaphore the returned int is error control 

int sem_destroy(sem_t *sem);//destroys a semaphore created with sim_init 

Gemeinsame Mutexes Funktionen (für Unix)

int pthread_mutex_init(pthread_mutex_t *p_mutex, const pthread_mutexattr_t *attr); //starts mutex pointed by p_mutex, use attr NULL for simple use 

int pthread_mutex_lock(pthread_mutex_t *p_mutex); //locks the mutex 

int pthread_mutex_unlock(pthread_mutex_t *p_mutex); //unlocks the mutex 

int pthread_mutex_destroy(pthread_mutex_t *p_mutex);//destroys the mutex 

Ich bin nicht sicher, warum Ihr Code funktioniert nicht, aber von dem, was Sie erklären, Sie needn‘ t Verwenden Sie einen Semaphor, da zwischen dem Client und dem Server nur die Verwendung einer gemeinsam genutzten Ressource nicht synchronisiert wird. Versuchen Sie, den Semaphor-Part mit einem Mutex neu zu schreiben, Sie werden sehen, dass es viel natürlicher erscheint und wahrscheinlich das Problem beheben wird.