Mise en œuvre d'un sémaphore binaire de la classe en C++
Donc, je suis en train de travailler sur un planificateur dans une de mes classes. Fondamentalement, nous sommes en prétendant qu'un seul thread peut s'exécuter en un temps. Nous sommes censés utiliser un sémaphore de la classe pour permettre à ces fils de bloquer eux-mêmes pour simuler le fil d'attente pour le CPU.
Le problème est, les fils semblent bloquer au mauvais moment et de l'exécuter au mauvais moment. Je me demandais si je suis absent de certaines compréhension conceptuelle d'un sémaphore et comment la mettre en œuvre. Je me demandais si je pouvais obtenir quelques commentaires sur mon œuvre. L'instructeur a fourni ce fichier d'en-tête que je n'ai pas modifié en aucune façon:
class Semaphore {
private:
int value;
pthread_mutex_t m;
pthread_cond_t c;
public:
/* -- CONSTRUCTOR/DESTRUCTOR */
Semaphore(int _val);
//~Semaphore();
/* -- SEMAPHORE OPERATIONS */
int P();
int V();
};
C'est ma mise en œuvre à l'aide de posix trucs:
Semaphore::Semaphore(int _val){
value = _val;
c = PTHREAD_COND_INITIALIZER;
m = PTHREAD_MUTEX_INITIALIZER;
}
int Semaphore::P(){
if(value <= 0){
pthread_cond_wait(&c, &m);
}
value--;
}
int Semaphore::V(){
value++;
if(value > 0){
pthread_cond_signal(&c);
}
}
Vous devez vous connecter pour publier un commentaire.
Vous êtes en négligeant de les verrouiller le mutex.
Deuxièmement, ce que vous avez ici est un comptage de sémaphore, pas un sémaphore binaire. Un sémaphore binaire n'a que deux états, et donc un
bool
variable:Impl:
Votre comptage sémaphore algorithme manque une boucle while, et les signaux de la sémaphore inutilement.
Logique originale, avec des écluses ajoutée (voir autre réponse):
La façon correcte:
Pour plus d'efficacité, de recueillir des informations concernant le signal ou pas à l'intérieur du mutex, mais alors ne le signal à l'extérieur le mutex. Mutex doit être tenu plus que quelques instructions machine que possible, car ils ajoutent de la contention, la réduction de la concurrence. Le signal peut prendre des centaines de cycles (voyage au noyau de faire la file d'attente de manipulation).
Vous devez utiliser une boucle lors de l'attente sur une variable de condition, car il peut les réveils intempestifs. Aussi, si vous signal à l'extérieur du mutex, l'état du signal ne permet pas toujours d'aller à la "destinée" de thread. Entre le
unlock
et lasignal
, un thread peut se faufiler dans et appelP
et décrémenter le mutex. Alors, le seul qui se réveille sur la condition doit ré-évaluer le test, sinon il faudra procéder de manière incorrecte.