zelur_em
27-03-2008, 14:05
Hallo allerseits.
Ich habe ein großes Problem bei der Programmierung einer
pthread-basierten Anwendung die auf die serielle Schnittstelle
zugreift.
Das Problem tritt immer dann auf, wenn ich in einer der
Threadfunktionen die Funktion nanosleep(timespec&, NULL),
usleep(unsigned long) oder sleep(unsigned int) für eine gewisse
Zeit schlafen legen will.
Hier ein kurzes Beispiel:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <iostream>
using namespace std;
int main () {
//int fd = open ("/dev/ttyS0", O_RDWR | O_NOCTTY);
//int fd = open ("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NONBLOCK);
int fd = open ("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1) {
perror ("error open");
return (1);
}
int rc;
char buf[5];
struct timespec t1;
t1.tv_sec = 0;
t1.tv_nsec = 300;
while (1) {
rc = read (fd, buf, 1);
if (rc > 1) {
cerr << endl << "read > 1" << endl;
} else if (rc == 1) {
//putchar (buf[0]);
cerr << buf[0];
} else {
/// Kommt nur vor wenn der Filedescriptor
/// auf nonblocking gestellt ist.
cerr << "i";
}
/// Der Knackpunkt
nanosleep (&t1, NULL);
}
return (0);
}
Das Codebeispiel geht davon aus, dass während des Programmstarts kontinuierlich Zeichen auf dem /dev/ttyS0 Device ankommen. Wenn jedoch die Gegenstelle, während des Programm läuft, mit dem Senden aufhört, so werden trotzdem weiterere eingehende Zeichen gemeldet. Kommentiert man jedoch die Zeile mit dem nanosleep aus, so funktioniert es einwandfrei. Ich versuche jetzt schon seit 2 Tagen den Fehler zu finden. Ohne Erfolg. Dabei ist dieses Beispiel schon eine stark vereinfachte Version bei der der Fehler auch ohne Multithreading auftritt. Ohne das nanosleep verursacht dieses kurze Beispiel 100% CPU-Last, da ja der Filedeskriptor entsprechend schnell abgefragt wird. Das Benutzen der blockierenden Version ist jedoch keine Alternative, da die Anwendung mit Hilfe von Interprozesskomunikation mit anderen Programmen in Verbindung steht.
Das Ganze ist mit dem g++ kompiliert. Das System ist ein Debian Etch.
Wäre über ein paar Ratschläge dankbar.
Falls ihr noch Infos braucht.... immer raus damit.
Ich habe ein großes Problem bei der Programmierung einer
pthread-basierten Anwendung die auf die serielle Schnittstelle
zugreift.
Das Problem tritt immer dann auf, wenn ich in einer der
Threadfunktionen die Funktion nanosleep(timespec&, NULL),
usleep(unsigned long) oder sleep(unsigned int) für eine gewisse
Zeit schlafen legen will.
Hier ein kurzes Beispiel:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <iostream>
using namespace std;
int main () {
//int fd = open ("/dev/ttyS0", O_RDWR | O_NOCTTY);
//int fd = open ("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NONBLOCK);
int fd = open ("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1) {
perror ("error open");
return (1);
}
int rc;
char buf[5];
struct timespec t1;
t1.tv_sec = 0;
t1.tv_nsec = 300;
while (1) {
rc = read (fd, buf, 1);
if (rc > 1) {
cerr << endl << "read > 1" << endl;
} else if (rc == 1) {
//putchar (buf[0]);
cerr << buf[0];
} else {
/// Kommt nur vor wenn der Filedescriptor
/// auf nonblocking gestellt ist.
cerr << "i";
}
/// Der Knackpunkt
nanosleep (&t1, NULL);
}
return (0);
}
Das Codebeispiel geht davon aus, dass während des Programmstarts kontinuierlich Zeichen auf dem /dev/ttyS0 Device ankommen. Wenn jedoch die Gegenstelle, während des Programm läuft, mit dem Senden aufhört, so werden trotzdem weiterere eingehende Zeichen gemeldet. Kommentiert man jedoch die Zeile mit dem nanosleep aus, so funktioniert es einwandfrei. Ich versuche jetzt schon seit 2 Tagen den Fehler zu finden. Ohne Erfolg. Dabei ist dieses Beispiel schon eine stark vereinfachte Version bei der der Fehler auch ohne Multithreading auftritt. Ohne das nanosleep verursacht dieses kurze Beispiel 100% CPU-Last, da ja der Filedeskriptor entsprechend schnell abgefragt wird. Das Benutzen der blockierenden Version ist jedoch keine Alternative, da die Anwendung mit Hilfe von Interprozesskomunikation mit anderen Programmen in Verbindung steht.
Das Ganze ist mit dem g++ kompiliert. Das System ist ein Debian Etch.
Wäre über ein paar Ratschläge dankbar.
Falls ihr noch Infos braucht.... immer raus damit.