Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

select in realtime umgebungen (multithreaded)

17 views
Skip to first unread message

Christian Parpart

unread,
Sep 28, 2002, 11:41:00 AM9/28/02
to
Hallo Leute,

folgendes problem, ich habe ein thread dessen aufgabe nur darin besteht in
einer while (runme) {} auf den Zustand von File Descriptoren mittels select
zu horchen und gegebenfalls einen IONotifier fuer die gegebene FD zu
senden, wenn sich was in, z.B. FD geaendert hat.

Code Auszug (C++):

enum IOType { ioRead = 1, ioWrite = 2, ioExcept = 4 };

class IONotify {
public:
virtual void notifyIO(int fd, IOType avail) = 0;
}

class IOWatcher {
public:
void watch(int fd, IONotify *toBeNotified, IOType ifAvail);
void unwatch(IONotify *, IOType ifAvail);
// ....
void run();
}

IOWatcher::run() ruft in einer Schleife select mit timeout 5 sekunden auf,
vorher werden jeweils die fd_set's neu gebildet.
Es ist klar dass, um Rekurssionen zu vermeiden, eine fd nicht zu select's
fd_set aufgenommen werden darf waehrend fuer diesen gerade ein extra thread
noch mit dem IONotify::notifyIO(fd, current) aktiv ist. Wenn notifyIO
beendet ist, und somit auch sein child-thread, wird diese FD und sein
notifier wieder auf "frei" gestellt, d.h. es darf an FD gehorcht werden.

Wenn aber er auf "frei" gestellt wird waehrend select noch am laufen ist,
und in dieser Zeit kein FD in den fd_sets von select seinen status aendert,
muss die gerade "frei" gestelt FD auf das timeout von select warten damit
darauf auch wieder gehorcht werden darf.

Problem ist dass das nicht einer Realtime Umgebung entspricht.
Also: wie kann ich select dazu bringen auf "Abruf" zu beenden?
Durch signale. Allerdings werden SIGUSR1 und SIGUSR2 auch in manchen pthread
implementationen schon von ihnen besetzt, also geht pselect nicht. oder
doch?

Jemand im irc gab mir den tipp eine pip zu nutzen.
"Create a pipe using pipe(), make select wait for new data
arriving on it, make another function that will write to the
write end of the pipe when select needs to wake up prematurely"
Aber, bitte seit mir nicht sauer, wenn mein Englisch gerade nichtsehr gut
ist, und ich mit Pipes sowie mit signalen noch keine gute Erfahrung habe.

Bitte, kann mir jemand helfen?


Danke schonmal,
Christian Parpart.

Ullrich von Bassewitz

unread,
Sep 28, 2002, 2:40:39 PM9/28/02
to
Christian Parpart <cpar...@surakware.net> wrote:
> "Create a pipe using pipe(), make select wait for new data
> arriving on it, make another function that will write to the
> write end of the pipe when select needs to wake up prematurely"
> Aber, bitte seit mir nicht sauer, wenn mein Englisch gerade nichtsehr gut
> ist, und ich mit Pipes sowie mit signalen noch keine gute Erfahrung habe.

Ich weiss zu wenig von Deiner Applikation um Dir andere Loesungen vorschlagen
zu koennen, aber die genannte sollte auf jeden Fall funktionieren.

Wenn Du eine Pipe aufmachst, und das zugehoerige Handle mit in Deinen fd_set
einfuegst, dann kann ein anderer Thread den IOWatcher Thread aufwecken, indem
er etwas in die Pipe schreibt.

Pipes erzeugen tust Du mit Funktion pipe(), "man pipe" gibt mehr
Informationen. Falls das nicht reicht, dann hilft "Advanced Programming in the
Unix Environment" von Altmeister Richard W. Stevens. Das Buch gibt's meines
Wissens auch in einer deutschen Uebersetzung, wie gut die ist weiss ich
allerdings nicht.

Gruss


Uz


--
Ullrich von Bassewitz u...@remove-to-reply.musoftware.de
8:32pm up 9 days, 6:47, 9 users, load average: 0.00, 0.05, 0.02

Christian Parpart

unread,
Sep 28, 2002, 10:18:25 PM9/28/02
to
Ullrich von Bassewitz inspired the electrons to say:

> Christian Parpart <cpar...@surakware.net> wrote:
>> "Create a pipe using pipe(), make select wait for new data
>> arriving on it, make another function that will write to the
>> write end of the pipe when select needs to wake up prematurely"
>> Aber, bitte seit mir nicht sauer, wenn mein Englisch gerade nichtsehr gut
>> ist, und ich mit Pipes sowie mit signalen noch keine gute Erfahrung habe.
>
> Ich weiss zu wenig von Deiner Applikation um Dir andere Loesungen
> vorschlagen zu koennen, aber die genannte sollte auf jeden Fall
> funktionieren.

Also, erstmal eins: ich habs hinbekommen :) Hurray!!!

> Wenn Du eine Pipe aufmachst, und das zugehoerige Handle mit in Deinen
> fd_set einfuegst, dann kann ein anderer Thread den IOWatcher Thread
> aufwecken, indem er etwas in die Pipe schreibt.

Genau das ist es, nur hat es der Mensch neulich nicht in IRC geschrieben,
und nur die pipe erwaehnt, jetzt bin ich dahinter gekommen, und bin total
froh dass es klappt. Zum Thema Pipe finde ich es nur schade dass es gleich
2 FDs gibt (lesen/schreiben) statt nur einer, wie bei allen anderen
devices. Ich weiss zwar nicht wass dabei raus kommt wenn ich in den read-fd
schreibe, oder aus der write-fd lese, aber eine fd haette es meiner meinung
nach auch getan. (waehre effektiver)

> Pipes erzeugen tust Du mit Funktion pipe(), "man pipe" gibt mehr
> Informationen. Falls das nicht reicht, dann hilft "Advanced Programming in
> the Unix Environment" von Altmeister Richard W. Stevens. Das Buch gibt's
> meines Wissens auch in einer deutschen Uebersetzung, wie gut die ist weiss
> ich allerdings nicht.

Also das Buch interessiert mich gerade wirklich! nur leider hab ich grad
kein Geld :(((. Also bleibt mir nur das Internet und die Bibliothek, ich
nehms auch auf English ;)

Vielen vielen Dank,
Christian Parpart.

Heinrich Schramm

unread,
Sep 29, 2002, 3:20:39 AM9/29/02
to
Christian Parpart <cpar...@surakware.net> wrote:

>Zum Thema Pipe finde ich es nur schade dass es gleich
>2 FDs gibt (lesen/schreiben) statt nur einer, wie bei allen anderen
>devices.

Normalerweise werden Pipes zur Interprozesskommunikation zwischen
Eltern- und Kindprozessen verwendet. Der Elternprozess richtet eine Pipe
ein und kreiert dann mit fork einen Kindprozess, der diese Pipe erbt.
Dann schliesst der Elternprozess z.B. die Leseseite der Pipe fd[0] und
der Kindprozess die Schreibseite fd[1]. Jetzt kann eine unidirektionale
Kommunikation stattfinden, wobei der Elternprozess schreibt und der
Kindprozess liest. Wenn man eine bidirektionale Kommunikation braucht,
richtet man eben zwei Pipes ein (und behandelt die Schreib- und
Leseseite bei der zweiten Pipe genau umgekehrt).

>> "Advanced Programming in the Unix Environment" von Altmeister
>> Richard W. Stevens.

>Also das Buch interessiert mich gerade wirklich! nur leider hab ich grad

>kein Geld :(((. Also bleibt mir nur das Internet und die Bibliothek, ich
>nehms auch auf English ;)

IMHO recht brauchbar ist auch "Linux-Unix-Systemprogrammierung" von
Helmut Herold (ISBN 3-8273-1512-3).

Gruss Heiner

Rainer Weikusat

unread,
Sep 29, 2002, 4:11:33 AM9/29/02
to
Christian Parpart <cpar...@surakware.net> writes:
> folgendes problem, ich habe ein thread dessen aufgabe nur darin besteht in
> einer while (runme) {} auf den Zustand von File Descriptoren mittels select
> zu horchen

[...]

> Wenn aber er auf "frei" gestellt wird waehrend select noch am laufen ist,
> und in dieser Zeit kein FD in den fd_sets von select seinen status aendert,
> muss die gerade "frei" gestelt FD auf das timeout von select warten damit
> darauf auch wieder gehorcht werden darf.
>
> Problem ist dass das nicht einer Realtime Umgebung entspricht.

Falls Du ohnehin multi-threaded arbeitest, warum machst Du select?

> Jemand im irc gab mir den tipp eine pip zu nutzen.
> "Create a pipe using pipe(), make select wait for new data
> arriving on it, make another function that will write to the
> write end of the pipe when select needs to wake up prematurely"

Es geht darum, das Du einen Deskriptor in deinem fdset hast, den Dein
Programm für interne Kommunikation verwendet.

Rainer Weikusat

unread,
Sep 29, 2002, 4:29:47 AM9/29/02
to
Christian Parpart <cpar...@surakware.net> writes:
> Zum Thema Pipe finde ich es nur schade dass es gleich
> 2 FDs gibt (lesen/schreiben) statt nur einer, wie bei allen anderen
> devices. Ich weiss zwar nicht wass dabei raus kommt wenn ich in den read-fd
> schreibe, oder aus der write-fd lese, aber eine fd haette es meiner meinung
> nach auch getan. (waehre effektiver)

Vergiß dieses Wort bitte. Du verwendest C++, dh Du hast Platz genug
für einen einzelnen int.

Christian Parpart

unread,
Sep 29, 2002, 8:07:07 AM9/29/02
to
Rainer Weikusat inspired the electrons to say:

Der Grund warum es brauchbarer (effektiver) ist, ist, dass ich eine Klasse
IOWatcher habe die, wenn sie auf ein weiteres FD horchen soll, als
parameter einen FD, eine Bitmaske (ioRead, ioWrite, ioExcept) und einen
notifier (eine Art Callback) uebergeben bekommt. Nun, man kann in fd[0] bei
einer pipe ja wohl schlecht auf ioWrite horchen, (denke ich), was mir das
design einer generischen Pipe Klasse etwas verschwierigte. Natuerlich
kuemmere ich nicht darum ob das objekt ein 4Byte mehr oder weniger hat
(hier nicht;-)

Aber ihr koennt euch mein Werk ansehen, unter
http://cvs.surakware.net/viewcvs.cgi/libswl/swl/io.h und deren .cpp
Das Projekt steht unter LGPL, also kein problem :-)

Ciao,
Christian Parpart

Christian Parpart

unread,
Sep 29, 2002, 8:07:57 AM9/29/02
to
Heinrich Schramm inspired the electrons to say:

>>> "Advanced Programming in the Unix Environment" von Altmeister
>>> Richard W. Stevens.
>
>>Also das Buch interessiert mich gerade wirklich! nur leider hab ich grad
>>kein Geld :(((. Also bleibt mir nur das Internet und die Bibliothek, ich
>>nehms auch auf English ;)
>
> IMHO recht brauchbar ist auch "Linux-Unix-Systemprogrammierung" von
> Helmut Herold (ISBN 3-8273-1512-3).

Um... und ich seh mein Geld schon schwinden :(

Christian Parpart

unread,
Sep 29, 2002, 8:11:37 AM9/29/02
to
Rainer Weikusat inspired the electrons to say:

>> Wenn aber er auf "frei" gestellt wird waehrend select noch am laufen ist,
>> und in dieser Zeit kein FD in den fd_sets von select seinen status
>> aendert, muss die gerade "frei" gestelt FD auf das timeout von select
>> warten damit darauf auch wieder gehorcht werden darf.
>>
>> Problem ist dass das nicht einer Realtime Umgebung entspricht.
>
> Falls Du ohnehin multi-threaded arbeitest, warum machst Du select?

Ganz einfach, select arbeitet sehr CPU sparend, wuerde ich statt dessen eine
Schleife haben in der ich jedes einzelne fd ueberpruefe ob sich was
geaendert hat kann das schon CPU fressen ;)
auch pollen soll auf die CPU gehen, bestes Beispiel ist hierfuer der KDE
Mail Client (KMail) der auch manchmal haengt. Dazu gab es mal eine riesen
Diskussion in der Mailinglist (_dass_ sie doch bitte select benutzen
moegen).

MfG,
Christian Parpart.

Rainer Weikusat

unread,
Sep 29, 2002, 8:58:50 AM9/29/02
to
Christian Parpart <cpar...@surakware.net> writes:
> Rainer Weikusat inspired the electrons to say:
> > Falls Du ohnehin multi-threaded arbeitest, warum machst Du select?
>
> Ganz einfach, select arbeitet sehr CPU sparend, wuerde ich statt dessen eine
> Schleife haben in der ich jedes einzelne fd ueberpruefe ob sich was
> geaendert hat kann das schon CPU fressen ;)
> auch pollen soll auf die CPU gehen, bestes Beispiel ist hierfuer der KDE
> Mail Client (KMail) der auch manchmal haengt. Dazu gab es mal eine riesen
> Diskussion in der Mailinglist (_dass_ sie doch bitte select benutzen
> moegen).

Natürlich mal wieder lauter bezahlte Fachkräfte ...

Du könntest in den einzelnen Threads blockiern (evtl). Falls jemand
anfängt, darüber zu 'diskutieren', warum mein keine Deskriptoren pollt,
obwohl das OS eine Schnittstelle zur Verfügung stellt, die
ausschließlich dem Zweck dient, daß zu vermeiden, sollte man ihn eine
Weile von Compilern fernhalten.

Heinrich Schramm

unread,
Sep 29, 2002, 9:41:40 AM9/29/02
to
Christian Parpart <cpar...@surakware.net> wrote:

[Zwei Buchempfehlungen:]


>Um... und ich seh mein Geld schon schwinden :(

Nope, beide Buecher gleichzeitig brauchst Du sicher nicht. Ich hatte das
zweite nur als Alternative vorgeschlagen, falls das erste nicht in
Deiner Bibliothek vorraetig sein sollte.

Gruss Heiner

Felix von Leitner

unread,
Sep 30, 2002, 7:50:41 AM9/30/02
to
Thus spake Christian Parpart (cpar...@surakware.net):

> folgendes problem, ich habe ein thread dessen aufgabe nur darin besteht in
> einer while (runme) {} auf den Zustand von File Descriptoren mittels select
> zu horchen und gegebenfalls einen IONotifier fuer die gegebene FD zu
> senden, wenn sich was in, z.B. FD geaendert hat.

Das ist eine geradezu auffallend dämliche Idee.
Threads setzt man gerade deswegen ein, weil man zu dämlich ist, direkt
select einzusetzen. Threads und select zu kombinieren ist an
Beklopptheit wirklich kaum zu überbieten.

Im Übrigen: man poll.

IONotifier, daß ich nicht lache.

Felix

Christian Parpart

unread,
Sep 30, 2002, 7:24:42 PM9/30/02
to
Felix von Leitner inspired the electrons to say:

1.) IONotifier, IOWatcher.... Das nennt man C++ Design, bestimmte
Eigenschaften/Aufgaben in Klassen zu packen und diese je nach
Anwendungszweck erben zu lassen. Die Grundidee ist nicht schlecht, und an
der Durchsetzung muss noch gefeilt werden. (mit jeder neuen Zeile). Und der
IOWatcher arbeitet Multithreaded damit sich der programmierer weiterhin
noch um seine Hauptaufgaben kuemmern kann, so er denn will ;)

Nun zerstoer mich nicht meine Euphorie, da wo ich doch grad verstehe :D,
btw, die Uni Bibliothek ist ein wahres Geschenk, was da alles fuer Buecher
stehen, die auch sowas erklaeren? Warum musste ich das erst heute
enddecken?

Ciao,
Christian.

Felix von Leitner

unread,
Oct 1, 2002, 5:39:48 AM10/1/02
to
Thus spake Christian Parpart (cpar...@surakware.net):
> > IONotifier, daß ich nicht lache.
> 1.) IONotifier, IOWatcher.... Das nennt man C++ Design, bestimmte
> Eigenschaften/Aufgaben in Klassen zu packen und diese je nach
> Anwendungszweck erben zu lassen. Die Grundidee ist nicht schlecht, und an
> der Durchsetzung muss noch gefeilt werden. (mit jeder neuen Zeile). Und der
> IOWatcher arbeitet Multithreaded damit sich der programmierer weiterhin
> noch um seine Hauptaufgaben kuemmern kann, so er denn will ;)

Grober Unfug. Wenn der Programmierer aus n Sockets lesen will, dann
macht er halt n Threads auf, in denen er jeweils read aufruft. Das ist
zwar unperformant und widerlich, aber der Programmierer kann sich seinem
Problem widmen, ohne sich mit dem System auskennen zu müssen. Ich
verstehen zwar nicht, wieso das ein Vorteil sein soll, aber viele Leute
(inklusive dir) möchten das ja wohl so haben.

> Nun zerstoer mich nicht meine Euphorie, da wo ich doch grad verstehe :D,
> btw, die Uni Bibliothek ist ein wahres Geschenk, was da alles fuer Buecher
> stehen, die auch sowas erklaeren? Warum musste ich das erst heute
> enddecken?

Christian, so entsteht Bloatware. Leute finden in der Unibibliothek
irgendein Schlipsträger-Buch über Design Patterns und UML und layern
sich dann eine Bloat-Orgie sondergleichen zurecht. Warte mit den Design
Patterns, bis du selber in deinen eigenen Projekten verstanden hast,
wieso man das so machen will.

Felix

Christian Parpart

unread,
Oct 1, 2002, 8:11:25 AM10/1/02
to
Felix von Leitner inspired the electrons to say:
> Thus spake Christian Parpart (cpar...@surakware.net):
>> > IONotifier, daß ich nicht lache.
>> 1.) IONotifier, IOWatcher.... Das nennt man C++ Design, bestimmte
>> Eigenschaften/Aufgaben in Klassen zu packen und diese je nach
>> Anwendungszweck erben zu lassen. Die Grundidee ist nicht schlecht, und an
>> der Durchsetzung muss noch gefeilt werden. (mit jeder neuen Zeile). Und
>> der IOWatcher arbeitet Multithreaded damit sich der programmierer
>> weiterhin noch um seine Hauptaufgaben kuemmern kann, so er denn will ;)
>
> Grober Unfug. Wenn der Programmierer aus n Sockets lesen will, dann
> macht er halt n Threads auf, in denen er jeweils read aufruft. Das ist
> zwar unperformant und widerlich, aber der Programmierer kann sich seinem
> Problem widmen, ohne sich mit dem System auskennen zu müssen. Ich
> verstehen zwar nicht, wieso das ein Vorteil sein soll, aber viele Leute
> (inklusive dir) möchten das ja wohl so haben.

Der Ursprung warum wir ueberhaupt mit der Bibliothek angefangen haben
(libswl) ist, weil ich unter Linux programmiere, und mein bester Kumpel
unter Windows. Zwar gibt Win32 vor POSIX compatible zu sein, das ist nicht
so ist sollte schnell erkannt sein :-) Des weiteren ist der Vorteil darin
einen abstracten Layer geschaffen zu haben der Plattformunabhaengig
arbeitet, da das Interface gleich bleibt. Einen Blick in die Win32 API
verraet mir, dass sie mir 1.) nicht besser gefaellt, aber 2.) moeglich ist
ein gleiches Interface zu schaffen. Das ist der Ursprung.

>> Nun zerstoer mich nicht meine Euphorie, da wo ich doch grad verstehe :D,
>> btw, die Uni Bibliothek ist ein wahres Geschenk, was da alles fuer
>> Buecher stehen, die auch sowas erklaeren? Warum musste ich das erst heute
>> enddecken?
>
> Christian, so entsteht Bloatware. Leute finden in der Unibibliothek
> irgendein Schlipsträger-Buch über Design Patterns und UML und layern
> sich dann eine Bloat-Orgie sondergleichen zurecht. Warte mit den Design
> Patterns, bis du selber in deinen eigenen Projekten verstanden hast,
> wieso man das so machen will.

Nun. 1.) Das Buch Design Patterns, haben wir vor ungefaehr 2 Jahren gelesen,
nun gehoert es zwar mir und es steht im Regal, aber es heisst ja nicht,
dass gleich jedes kleine Pattern angewannt werden muss.
2.) Ich habe gezielt nach einem Buch gesucht, da mir ineinem anderen thread
welche empfohlen wurden :)

Christian.

Felix von Leitner

unread,
Oct 1, 2002, 11:00:22 AM10/1/02
to
Thus spake Christian Parpart (cpar...@surakware.net):
> Der Ursprung warum wir ueberhaupt mit der Bibliothek angefangen haben
> (libswl) ist, weil ich unter Linux programmiere, und mein bester Kumpel
> unter Windows.

Dann muß dein Kumpel die Konsequenzen tragen und so lange bitterlich
leiden, bis ihm eines Tages ein Gehirn wächst. Wieso willst du den Rest
der Welt für die Fehlentscheidung deines Freundes leiden lassen?

Felix

Christian Parpart

unread,
Oct 1, 2002, 6:03:43 PM10/1/02
to
Felix von Leitner inspired the electrons to say:

> Thus spake Christian Parpart (cpar...@surakware.net):

Ich akzeptiere Menschen die Windows vorziehen! Und... ja, sogar stolz darauf
sind, weil sie es begruenden koennen; ich lasse ihnen ihre Meinung.
Schliesslich, akzeptiert er, dass unsere Dienste von einem Linux server aus
gemeisstert werden. Ich definitiv bin ein Kind UNIX'. Und... ja, sogar ich
kann es begruenden.

Des weiteren ist Er ein hervorragender Programmierer; wir programmieren seit
schon ueber 8 Jahren im Team, wir arbeiten z.B. derzeit an einer
Programmiersprache und an deren Implementation. Wir habe bereits schon
ueber 18,000 Zeilen *produktiven* Code. Ich kenne keinen mit dem ich mich
so tief ueber Sprachen/Design/Algorithmen und Probleme reden/philosophieren
und diskutieren kann.

Es ist nicht richtig, Menschen nach ihrer Wahl des Betriebssystems zu
beurteilen!

Danke,
Christian.

0 new messages