Pro-Linux

Pro-Linux Diskussions- und Hilfeforum
Aktuelle Zeit: 12. Nov 2018 19:07

Alle Zeiten sind UTC+01:00




Ein neues Thema erstellen  Auf das Thema antworten  [ 6 Beiträge ] 
Autor Nachricht
BeitragVerfasst: 10. Jun 2008 17:08 
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?


Nach oben
   
 Betreff des Beitrags:
BeitragVerfasst: 11. Jun 2008 12:53 
Offline
Benutzeravatar

Registriert: 11. Feb 2006 19:10
Beiträge: 3569
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.


Nach oben
   
 Betreff des Beitrags:
BeitragVerfasst: 17. Jun 2008 8:48 
Vielen Dank für deine Antwort. War für mich in erster Linie wichtig, zu wissen dass ich das richtig verstanden habe.
Zitat:
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?
Zitat:
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.


Nach oben
   
 Betreff des Beitrags:
BeitragVerfasst: 17. Jun 2008 21:24 
Offline
Benutzeravatar

Registriert: 11. Feb 2006 19:10
Beiträge: 3569
Zitat:
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.
Zitat:
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.


Nach oben
   
 Betreff des Beitrags:
BeitragVerfasst: 19. Jun 2008 15:45 
Zitat:
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!
Zitat:
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?


Nach oben
   
 Betreff des Beitrags:
BeitragVerfasst: 19. Jun 2008 18:07 
Offline
Benutzeravatar

Registriert: 11. Feb 2006 19:10
Beiträge: 3569
Zitat:
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.


Nach oben
   
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen  Auf das Thema antworten  [ 6 Beiträge ] 

Alle Zeiten sind UTC+01:00


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 0 Gäste


Sie dürfen keine neuen Themen in diesem Forum erstellen.
Sie dürfen keine Antworten zu Themen in diesem Forum erstellen.
Sie dürfen Ihre Beiträge in diesem Forum nicht ändern.
Sie dürfen Ihre Beiträge in diesem Forum nicht löschen.
Sie dürfen keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
Powered by phpBB® Forum Software © phpBB Limited
Deutsche Übersetzung durch phpBB.de