J'écris un programme (pour les devoirs) qui simule une salle de bain unisexe. Seules 4 personnes sont autorisées à un moment et à des hommes et une femme ne peuvent pas entrer si l'autre sexe utilise déjà la salle de bain. Mon problème est de permettre à un max de 4 personnes dans la salle de bain. Comme vous pouvez le constater à partir de la sortie, une seule personne ne fait que monter dans les toilettes à la fois. Voici mon code:
const int Delayx = 60; int i; int restroom = 0; int Menwaiting = 0; int Womenwaiting = 0; semaphore max_capacity; semaphore woman; semaphore man; semaphore mutex; semaphore restroomcount; void Delay(void) { int DelayTime; DelayTime = random(Delayx); for (i = 0; i<DelayTime; i++); } void Woman(void) { // for(;;){ Womenwaiting++; //wait(mutex); wait(woman); wait(max_capacity); //wait(woman); wait(mutex); wait(restroomcount); cout << "A Woman has entered Restroom"<<endl; cout << "People in the Restroom:" << restroom++ <<endl <<endl; signal(restroomcount); Womenwaiting--; Delay(); wait(restroomcount); cout << "A woman has exited Restroom"<<endl; cout << "People in the Restroom:" << restroom-- <<endl<<endl; signal(restroomcount); signal(mutex); signal(max_capacity); if(Menwaiting > Womenwaiting){ signal(man); } else{ signal(woman); } //signal(max_capacity); //signal(man); // } } void Man(void) { // for(;;){ Menwaiting++; //wait(mutex); wait(man); wait(max_capacity); //wait(man); wait(mutex); wait(restroomcount); cout <<"A Man has entered the Restroom"<<endl; cout <<"People in the Restroom:" << restroom++ <<endl<<endl; signal(restroomcount); Menwaiting--; //signal(mutex); Delay(); //wait(mutex); wait(restroomcount); cout << "A man has exited the Restroom"<<endl; cout <<"People in the Restroom:" << restroom-- <<endl<<endl; signal(restroomcount); signal(mutex); signal(max_capacity); if(Womenwaiting > Menwaiting){ signal(woman); } else{ signal(man); } //signal(max_capacity); //signal(woman); //} } void main() { initialsem(woman,1); initialsem(man,1); initialsem(max_capacity,4); initialsem(mutex,1); initialsem(restroomcount,1); cobegin { Woman(); Woman(); Woman(); Woman(); Woman(); Man(); Man(); Man(); Man(); Man(); } }
3 Réponses :
Je pense que vous avez trop de sémaphores. Vos sémaphores homme / femme se rendent à 1 personne à la fois. Envisagez d'utiliser des variables d'état protégées par des mutiles (sexe actuel de salle de bain, nombre de personnes dans la salle de bain) plutôt que tant de sémaphores différents. P>
Conservez-vous une commande de ligne ou des personnes peuvent-elles passer en fonction du sexe de toilettes actuel? Par exemple, si vous avez une femme, une femme, une femme, une femme, une femme, la 4ème femme est autorisée à sauter l'homme et à aller dans les toilettes, ou à faire la sortie des 3 femmes, puis l'homme entre / sortit, puis la femme peut entrer ? C'est un problème plus facile que de permettre un saut. P>
est l'utilisation de sémaphores une exigence? Par exemple, dans le pseudo-code "C ++", une implémentation ressemblerait à:
Premier permet de créer un objet d'état et une fonction valide les transitions entre les états p> permettrons Créez également une référence globale à l'état actuel et une fonction permettant de mettre à jour l'état actuel en fonction de certains éléments suivants d'état souhaité p> alors nous créons un vecteur global pour tenir les états et Une fonction représentant une filtration de femmes essayant d'aller à la salle de bain p> et la fonction principale avec la logique de boucle de processus et l'initialisation p> Notez que je n'utilise aucun sémaphores ou verrouillage mutex, la seule primitive de verrouillage que j'utilise est la CAS (adresse, ancien_value, nouvelle_value) (comparaison et échange). Cette primitive compare atomiquement un pointeur (adresse) et s'il contient toujours (Old_Value), alors il l'attribue NEW_Value et réussit, sinon elle échoue. En outre, vous avez encore besoin d'une serrure globale pour le STD :: Vector stockant les états que je n'ai pas inclus dans le code (vous pouvez aussi simplement les fuir, mais je les stocke quelque part afin de pouvoir penser que ceux-ci devraient être supprimés une fois que vous savez Comment GC pourrait-on faire pour travailler dans ces cas) P> Étant donné que tous mes états intermédiaires sont intégrés (inhumité de style LISP / clojure), la conflit (et donc, la famine) des threads s'améliore considérablement. Dans votre exemple, l'ensemble des états est petit (juste un tas de personnes), ce n'est pas dommage que nous ne supprimons pas les états usés. P> Cependant, même avec les problèmes que j'ai mentionnés, je pense que vous conviendrez que la logique de ce qui se passe est beaucoup plus explicite et lisible. p> p>
Votre méthode ISPTY () est fausse. La mise en œuvre actuelle revient vrai si quelqu'un est dans les toilettes. Je pense que vous voulez des hommes + des femmes <= 0 (le '<' est là parce que cela peut potentiellement se produire s'il n'est pas codé contre.)
Vous avez raison, je l'ai réparé. Merci. Je ne m'inquiète pas de la
problèmes avec la question strong> Le traitement de la file d'attente de la salle de bain doit être séparé de la génération des personnes dans la file d'attente - si elle n'exécute pas un fil séparé au moins une fois la file d'attente. p> en supposant qu'il existe essentiellement des files d'attente distinctes d'hommes et de femmes - non mélangées dans un ordre fixe, sinon le problème n'a aucun sens d'utiliser un sémaphore. P> Le problème ne décrit pas combien de personnes entrent à entrer lorsque la condition a raison, toilettes masculines avec plus d'hommes, remplissez-vous à 4 ou seulement jusqu'à ce que la file d'attente des hommes soit à nouveau moins que les femmes? P> Même même Donc, le problème tel que décrit (et basé sur un code d'échantillon sans threading) ne fonctionne pas bien avec un sémaphore à mon avis, le problème principal est que le sémaphore ne cédit pas facilement le nombre de comptes et une attente réussie change le compte. P> La chose intéressante que je vois dans le problème est l'inefficacité de la longueur de la file d'attente proche et de la négociation entre le refus d'un autre sexe dans les toilettes et de la chance que les personnes restantes dans les toilettes ne quittent le nombre. du même sexe devient plus grand à nouveau. Permet de le faire face, c'est unisexe et il devrait donc permettre à 4 personnes à titre de sexe;) p> Avoir 1 sémaphore et penser que vous devriez vérifier le sémaphore lorsqu'une personne pénètre dans la file d'attente ou quand quelqu'un quitte la salle de bain. P> Vous pouvez alors avoir une «file d'attente» chacune pour les hommes et les femmes (à partir de celui-ci, il s'agit essentiellement d'un compte). Ces files d'attente ne sont pas vraiment liées ou se limitant mutuellement en termes d'entrée et n'ont donc rien à voir avec des sémaphores. Chacun pourrait suivre un modèle de fournisseur sans verrouillage, mais vous trouverez peut-être plus facile d'utiliser un mutex pour synchroniser afin que vous puissiez examiner la taille des files d'attente et les manipuler. Dans ce qui suit, je viens d'utiliser directement le nombre de comptes, il devrait plutôt utiliser une forme de verrouilliedinCrètes et d'InterverideDeCrementation pour protéger contre l'ajout et la suppression de personnes de la même file d'attente. P> dans le rugueux, salle de bain.h
Le code d'origine n'est pas très oo.
Vous devez donc utiliser un sémaphore, les choses intéressantes sur un sémaphore constituent l'enregistrement de multiples utilisations (contrairement à mutex) et s'il n'y a pas d'espace libre, cela n'attendra pas. Il ne discrimine pas cependant entre ceux qui attendent, il ne dit que s'il n'y a pas d'espace libre. P> Bathroom b1;
addPeople() {
while(true) {
// randomly add people
Delay();
b1.AddMen();
b1.AddWomen();
}
}
int main(){
thread( addPeople );
b1.run();
}
Quelle partie de ce code est censé être responsable de la prévention d'un homme d'entrer dans les toilettes, s'il y a déjà une femme là-bas et vice-versa?
Cette affectation est-elle censée être une seule filetée? Utilisez des threads? Coroutines?
@Dgnorton - Semaphores. J'utilise un interprète appelé Baci pour simuler des processus concurrents.
Je comprends que ceci est une mission, mais il a-t-il vraiment besoin d'être fait avec des sémaphores (est-ce un exercice de sémaphore)? Une variable de condition pourrait plus facilement décrire la condition lorsqu'un homme / femme peut entrer: vous ne faites que signaler lorsque la condition a changé et que les threads se vérifient, que ce soit bien de participer.