Hinweis: Das Forum wird geschlossen! Neue Registrierungen sind nicht mehr möglich!

 Zurück zu Pro-Linux   Foren-Übersicht   FAQ     Suchen    Mitgliederliste
Verständnisfrage zu pthread_cond_timedwait()

 
Neuen Beitrag schreiben   Auf Beitrag antworten    Pro-Linux Foren-Übersicht -> Programmieren - C
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
_CHRIS_
Gast





BeitragVerfasst am: 10. Jun 2008 17:08   Titel: Verständnisfrage zu pthread_cond_timedwait()

Hallo zusammen.

Mir ist bei Verwendung der Funktion pthread_cond_timedwait() noch etwas unklar und was ich bisher hier gesehen habe bin ich zuversichtlich, dass mir hier geholfen werden kann.

Mein Code in einem Thread sieht in etwa so aus:
Code:
pthread_mutex_lock( &mutex );
pthread_cond_timedwait( &cond, &mutex, &abstime );
/*
Code ...
*/
pthread_mutex_unlock( &mutex );


Dieser Thread läuft unter der Scheduling-Policy SCHED_FIFO (Priorität 1), alle anderen unter SCHED_OTHER. Mir ist wichtig, dass dieser Thread so gut wie möglich im Sekundentakt aufgerufen wird, was ich über die Struktur abstime mache. Die condition variable spielt keine Rolle, sie wird von keinem keinem anderen thread freigegeben.

Der Thread wird also immer dann aktiviert, wenn die entsprechende Zeit zu abstime erreicht ist. Soweit so gut. Nun zu meiner Frage:

Was passiert, wenn genau zu dieser Zeit der Mutex von einem anderen Thread blockiert wird? Dann muss doch mein höher priorisierter Thread solange warten bis der Mutex wieder freigegeben wurde, womit sich ein gewisser Jitter auf meinem Sekundentakt ergibt.

Ist das richtig? Oder habe ich da noch etwas übersehen?
 

Janka



Anmeldungsdatum: 11.02.2006
Beiträge: 3569

BeitragVerfasst am: 11. Jun 2008 12:53   Titel:

Genau so ist es. Die Priorität spielt nur eine Rolle, wenn mehr als ein Thread im System im Zustand "runable" ist. Threads/Prozesse, die auf irgendeine Bedingung blockieren, sind da völlig außen vor.

Will man diesen Jitter verhindern, muss man auf das blockierende Warten auf den Mutex im höher priorisierten Thread verzichten und ihn stattdessen beim Zurückkehren aus der Wartezeit nicht blockierend abfragen (erlaubt, weil kein anderer Thread mit Kenntnis des Mutexes diesen Thread unterbrechen kann), und dann die Aktionen durchführen, die trotz der Sperre noch möglich sind.

Man kann auch komplett ohne Mutexes arbeiten, wenn man darauf achtet, dass die Aktionen, die die einzelnen Threads zur Datenübergabe durchführen, in sich atomar sind. Dann gibt es auch keinen zusätzlichen Jitter. Im allgemeinen Fall wird es aber reichen, die kritischen Abschnitte einfach so kurz wie möglich zu halten. Ein bisschen Jitter gibt es immer, weil auch die Prozessumschaltung nicht zwangsläufig immer gleich schnell abläuft und Interrupts auf Kernelebene ja noch höher priorisiert sind als jeder Prozess.

Auch an mlock() denken!

Was genau soll das denn werden?
Janka
_________________
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.
 
Benutzer-Profile anzeigen Private Nachricht senden

_CHRIS_
Gast





BeitragVerfasst am: 17. Jun 2008 8:48   Titel:

Vielen Dank für deine Antwort. War für mich in erster Linie wichtig, zu wissen dass ich das richtig verstanden habe.

Janka hat folgendes geschrieben::
Will man diesen Jitter verhindern, muss man auf das blockierende Warten auf den Mutex im höher priorisierten Thread verzichten und ihn stattdessen beim Zurückkehren aus der Wartezeit nicht blockierend abfragen (erlaubt, weil kein anderer Thread mit Kenntnis des Mutexes diesen Thread unterbrechen kann), und dann die Aktionen durchführen, die trotz der Sperre noch möglich sind.


Was meinst du damit genau? Was bedeuted "nicht blockierend abfragen"? Heißt das, dass ich die Anweisung
Code:
pthread_cond_timedwait( &cond, &mutex, &abstime );

ohne vorheriges
Code:
pthread_mutex_lock( &mutex );

ausführen soll?

Janka hat folgendes geschrieben::
Was genau soll das denn werden?

Es geht um ein Embedded Linux System, in dem mehrere Threads auf die I2C-Bus-Schnittstelle zugreifen sollen, auch der höher priorisierte. Darum brauche in den Mutex.
 

Janka



Anmeldungsdatum: 11.02.2006
Beiträge: 3569

BeitragVerfasst am: 17. Jun 2008 21:24   Titel:

_CHRIS_ hat folgendes geschrieben::

Was meinst du damit genau? Was bedeuted "nicht blockierend abfragen"? Heißt das, dass ich die Anweisung
Code:
pthread_cond_timedwait( &cond, &mutex, &abstime );

ohne vorheriges
Code:
pthread_mutex_lock( &mutex );

ausführen soll?

Nein. Es gibt dafür pthread_mutex_trylock(). Wenn das fehlschlägt, kann der am höchsten priorisierte Thread ja trotzdem weiterarbeiten. Er darf halt nur nicht auf die gesperrte Ressource zugreifen.

_CHRIS_ hat folgendes geschrieben::

Es geht um ein Embedded Linux System, in dem mehrere Threads auf die I2C-Bus-Schnittstelle zugreifen sollen, auch der höher priorisierte. Darum brauche in den Mutex.

Geschieht das Locking auf Datenpaketebene oder auf Transaktionsebene (mehrere Slaves synchron schalten)? Wenn Transaktionen unterbrochen werden dürfen, könnte man da auch noch einiges verbessern und den Jitter für den höchst priorisierten Thread so verringern.

Janka
_________________
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.
 
Benutzer-Profile anzeigen Private Nachricht senden

_CHRIS_
Gast





BeitragVerfasst am: 19. Jun 2008 15:45   Titel:

Janka hat folgendes geschrieben::
Nein. Es gibt dafür pthread_mutex_trylock(). Wenn das fehlschlägt, kann der am höchsten priorisierte Thread ja trotzdem weiterarbeiten. Er darf halt nur nicht auf die gesperrte Ressource zugreifen.

Danke!

Janka hat folgendes geschrieben::
Geschieht das Locking auf Datenpaketebene oder auf Transaktionsebene (mehrere Slaves synchron schalten)? Wenn Transaktionen unterbrochen werden dürfen, könnte man da auch noch einiges verbessern und den Jitter für den höchst priorisierten Thread so verringern.

Da steck ich noch nicht so tief drin. Den exakten Ablauf der Kommunikation regelt ja der I2C-Treiber für mich. Was ich bis jetzt mache ist folgendes:
Zuerst öffne ich den Bus:
Code:
i2c_fd = open("/dev/i2c-1", O_RDWR);

der Filedeskriptor i2c_fd ist global deklariert.
Jedes mal wenn ich mit einem Slave kommunizieren will ruf ich zuerst ioctl() auf:
Code:
ioctl(i2c_fd, I2C_SLAVE, slaveaddress);

und greife dann mit read() und write() auf den Bus zu.

Den Mutex benutze ich, damit ich sicher gehen kann, dass nicht z.B. das falsche Byte an den falschen Slave geschickt wird. Wenn der Treiber das selbst regelt, wenn ich z.B. jedem Slave einen eigenen Filedeskriptor zuweise, kann ich natürlich auf den Mutex verzichten.
Leider weiß ich nicht, wie der Treiber genau funktioniert. Wo finde ich denn dazu eine Dokumentation?
 

Janka



Anmeldungsdatum: 11.02.2006
Beiträge: 3569

BeitragVerfasst am: 19. Jun 2008 18:07   Titel:

_CHRIS_ hat folgendes geschrieben::

Zuerst öffne ich den Bus:
Code:
i2c_fd = open("/dev/i2c-1", O_RDWR);

der Filedeskriptor i2c_fd ist global deklariert.
Jedes mal wenn ich mit einem Slave kommunizieren will ruf ich zuerst ioctl() auf:
Code:
ioctl(i2c_fd, I2C_SLAVE, slaveaddress);

und greife dann mit read() und write() auf den Bus zu.

Den Mutex benutze ich, damit ich sicher gehen kann, dass nicht z.B. das falsche Byte an den falschen Slave geschickt wird.

Das ist WIMRE unnötig, denn der Treiber selbst verschickt bereits ganze Nachrichten, sortiert also die Daten aus den Filedeskriptoren selbst und kümmert sich auch um das Timing.

Zitat:

Leider weiß ich nicht, wie der Treiber genau funktioniert. Wo finde ich denn dazu eine Dokumentation?

Use the Source, Luke! /usr/src/linux/drivers/i2c/...

Janka
_________________
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.
 
Benutzer-Profile anzeigen Private Nachricht senden

Beiträge vom vorherigen Thema anzeigen:   
     Pro-Linux Foren-Übersicht -> Programmieren - C Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehen Sie zu:  

Powered by phpBB © phpBB Group
pro_linux Theme © 2004 by Mandaxy