Hallo, wir haben eine Semaphore, welche sehr oft ausgelöst wird, bevor es abgefragt wird (ist aber auch so gewollt). Jetzt suchen wir eine möglichkeit die Semaphore auf einmal wieder auf 0 zu setzen. Quasi ein reset. Das haben wir aber nichts zu gefunden. Haben es dann einfach mit sem_init neu gemacht. Hat auch funktioniert (in einem fall zumindest). Aber es heißt auch Initializing a semaphore that has already been initialized results in undefined behavior. Jetzt fallen mir nur die möglichkeiten ein 1) sem_destroy und dann neu initialisieren mit sem_init 2) sem_getvalue und dann eine for-schleife mit sem_post Der wert ist bei ca. 30000. Was wäre schneller/schöner? Gibt es sonst keine Möglichkeit den Wert wieder zurückzusetzen?
Johannes schrieb: > Was wäre schneller/schöner? Gibt es sonst keine Möglichkeit den Wert > wieder zurückzusetzen? Beides schlecht, der Sinn einer Semaphore ist, dass sie in den Kontexten dekrementiert wird, wo sie auch inkrementiert wurde. Dann kommt man automatisch wieder auf 0. Johannes schrieb: > wir haben eine Semaphore, welche sehr oft ausgelöst wird, bevor es > abgefragt wird (ist aber auch so gewollt). Ich glaube da musst du den Sinn dahinter mal genauer beschreiben, eine reine Semaphore ist wohl nicht die Lösung.
Das verstehe ich nicht. Mit Semaphoren soll ja etwas signalisiert werden. Du hast 30.000 Signale abgefeuert, und jetzt sind die auf einen Schlag alle ungültig und sollen ungenutzt verworfen werden? Bist du sicher, dass Semaphoren das geeignete Mittel für deinen Anwendungsfall sind?
:
Bearbeitet durch User
Rolf M. schrieb: > Das verstehe ich nicht. Mit Semaphoren soll ja etwas signalisiert > werden. Du hast 30.000 Signale abgefeuert, und jetzt sind die auf einen > Schlag alle ungültig und sollen ungenutzt verworfen werden? Bist du > sicher, dass Semaphoren das geeignete Mittel für deinen Anwendungsfall > sind? Wie kommst du auf Signale?
Johannes schrieb: > Jetzt fallen mir nur die möglichkeiten ein > 1) > sem_destroy Ebenfalls undefiniert wenn noch sem_wait() aktiv sind. > 2) > sem_getvalue > und dann eine for-schleife mit > sem_post Nein. a) Da du nicht weißt ob noch andere Programmteile an der Semaphore rumbasteln reicht einmal sem_getvalue() vor der Schleife nicht. Der Wert kann sich wärend die Schleife läuft ändern. b) sem_post() erhöht die Semaphore. Wie willst du durch Inkrementieren auf 0 kommen? sem_trywait() ohne sem_getvalue() wäre möglich. > Der wert ist bei ca. 30000. > Was wäre schneller/schöner? Eine bessere Programmstruktur. Das klingt sehr danach dass jemand besonders Clever sein wollte aber sich in eine Ecke programmiert hat. Jetzt, statt den Fehler zuzugeben und zu beseitigen, soll was zusammengebastelt werden. Zu jedem sem_post() gehört ein sem_wait() im Code.
cppbert schrieb: > Wie kommst du auf Signale? Rolf M. schrieb: > Mit Semaphoren soll ja etwas signalisiert werden. Es wurde also 30.000 mal etwas signalisiert. Wie Felix schon schreibt, gehört das inkrementieren und dekrementieren normalerweise zusammen, und da sollte nix auseinanderlaufen. Die Frage ist also, warum das jetzt alles ungehört verworfen werden soll.
Klingt als bräuchtest du eher eine Condition Variable statt einer Semaphore. Dort kann man Zähler beliebig setzen. Man muss aber aufpassen es genau richtig zu machen um keine Ereignisse zu verpassen.
Rolf M. schrieb: > Rolf M. schrieb: >> Mit Semaphoren soll ja etwas signalisiert werden. > > Es wurde also 30.000 mal etwas signalisiert. das mit dem Signalisieren hast du als 1. geschrieben - ist aber würde ich sagen der falsche Begriff - es geht bei Semaphoren doch um die Absicherung von Ressourcen die nur eine bestimmte Menge an Parallel-Zugriffen erlauben, das kann was mit signalisieren zu tun haben muss es aber auch überhaupt nicht
cppbert schrieb: > Rolf M. schrieb: >> Rolf M. schrieb: >>> Mit Semaphoren soll ja etwas signalisiert werden. >> >> Es wurde also 30.000 mal etwas signalisiert. > > das mit dem Signalisieren hast du als 1. geschrieben - ist aber würde > ich sagen der falsche Begriff - es geht bei Semaphoren doch um die > Absicherung von Ressourcen die nur eine bestimmte Menge an > Parallel-Zugriffen erlauben, das kann was mit signalisieren zu tun haben > muss es aber auch überhaupt nicht Ich denke, Du irrst Dich. Ein "Semaphor" ist zunächst das pyhsische Mittel um ein "Signal" zu geben. In der Informatik ist das eine Datenstruktur, in der Informationen, in der physischen Form von Spannungen in Speicherstellen, gespeichert sind. Im übrigen irrst Du Dich m.M.n. auch mit der Aussage, dass die Absicherung von Resourcen unter Umständen nichts mit Signalisierung zu tun haben kann. Da Informationen - und die Tatsache das eine Resource belegt ist, ist eine Information -, nur durch Signal übertragen resp. repräsentiert werden können, hat das zwingend grundsätzlich mit Signalen zu tun. Siehe die entsprechenden Einträge in der Wikipedia unter "Signal" und "Semaphor".
So wie im Anhang könnte man es mit einer Condition Variable machen. Der main-Thread "sendet" Signale indem er den signalCounter erhöht, und der zweite Thread empfängt sie. Er setzt dabei jedes mal den signalCounter auf 0, d.h. konsumiert viele Signale auf einmal. Der main-Thread könnte den Counter auch auf 0 zurück setzen oder sonstwie beliebig bearbeiten, solange das innerhalb des Mutex passiert. Die Condition Variable stellt hier sicher, dass man keine Ereignisse verpasst. Der selbe Mechanismus wird auch benutzt um den Thread zu beenden; "run" wird, geschützt durch den Mutex, auf "false" gesetzt, um Beendigung zu signalisieren. Die Condition Variable wird benutzt, um den Thread in diesem Fall sofort aufzuwecken sodass er dann zurückkehren kann.
cppbert schrieb: > Rolf M. schrieb: >> Rolf M. schrieb: >>> Mit Semaphoren soll ja etwas signalisiert werden. >> >> Es wurde also 30.000 mal etwas signalisiert. > > das mit dem Signalisieren hast du als 1. geschrieben Deshalb hat mich deine Rückfrage etwas verwundert. > - ist aber würde ich sagen der falsche Begriff - es geht bei Semaphoren doch > um die Absicherung von Ressourcen die nur eine bestimmte Menge an > Parallel-Zugriffen erlauben, das kann was mit signalisieren zu tun haben > muss es aber auch überhaupt nicht Ich sehe es genau anders herum. Mit Semaphoren signalisiert man Dinge. Das kann mit der Absicherung von Ressourcen zu tun haben, muss aber nicht.
Rolf M. schrieb: > Mit Semaphoren signalisiert man Dinge. signalisieren wie Posix-Signal oder eher wie vermerken
Aufgrund des Diskussionsverlaufs als Hilfestellung: https://www.geeksforgeeks.org/mutex-vs-semaphore/ Ansonsten, solange der TO nicht schreibt worum es ihm konkret geht (Stichwort Use-Case, Sprache, Beispiel-Code) ist dies eine Freitagsdiskussion (welche ja aber auch durchaus mal Spass machen kann ;-)
cppbert schrieb: > Rolf M. schrieb: >> Mit Semaphoren signalisiert man Dinge. > > signalisieren wie Posix-Signal oder eher wie vermerken Signalisieren in dem Sinne, dass ein Thread (in der Regel blockierend) auf ein Ereignis wartet, dessen Eintreten durch einen anderen Thread eben signalisiert wird.
Ich denke, der TO hat seine Verwendung des Semaphors korrigiert und sorgt sich nicht mehr um die Bedeutung von "Signal".
Ein ganz typischer Anwendungsfall ist ja die Übergabe von Arbeits-Paketen (Tasks). Für jeden Task würde man die Semaphore erhöhen, und die Worker-Threads versuchen die Semaphore zu dekrementieren; wenn sem_wait zurückkehrt ist also ein Task vorhanden, und er wurde automatisch "abgebucht" (die Semaphor dekrementiert). Wenn man jetzt alle Tasks abbrechen o.ä. will, müsste man die Semaphor zurücksetzen. Das geht ja wie schon festgestellt nicht; daher der Vorschlag mit der Condition Variable. Condition Variables ermöglichen es praktisch beliebige eigene Synchronisationsmechanismen zu bauen: Über eine beliebig modifizierbare Datenstruktur (in meinem Beispiel der "signalCounter", als einfacher Integer), die z.B. auch eine Liste/Schlange sein kann, kann man den Workern signalisieren was/wie viel zu tun ist. Der Mutex stellt die Konsistenz sicher, und die Condition Variable erlaubt es den Threads blockierend zu warten ohne unnötig aufzuwecken.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.