Forum: PC-Programmierung semaphore wert zurücksetzen


von Johannes (Gast)


Lesenswert?

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?

von Felix U. (ubfx)


Lesenswert?

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.

von Rolf M. (rmagnus)


Lesenswert?

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
von cppbert (Gast)


Lesenswert?

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?

von Michael Gugelhupf (Gast)


Lesenswert?

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.

von Rolf M. (rmagnus)


Lesenswert?

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.

von Programmierer (Gast)


Lesenswert?

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.

von cppbert (Gast)


Lesenswert?

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

von Theor (Gast)


Lesenswert?

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".

von Programmierer (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Rolf M. (rmagnus)


Lesenswert?

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.

von cppbert (Gast)


Lesenswert?

Rolf M. schrieb:
> Mit Semaphoren signalisiert man Dinge.

signalisieren wie Posix-Signal oder eher wie vermerken

von Mikro 7. (mikro77)


Lesenswert?

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 
;-)

von Rolf M. (rmagnus)


Lesenswert?

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.

von A. S. (Gast)


Lesenswert?

Ich denke, der TO hat seine Verwendung des Semaphors korrigiert und 
sorgt sich nicht mehr um die Bedeutung von "Signal".

von Programmierer (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.