App installieren
How to install the app on iOS
Follow along with the video below to see how to install our site as a web app on your home screen.
Anmerkung: This feature may not be available in some browsers.
Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden.
Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Prozess/Thread-Kommunikation unter Linux
- Ersteller i_hasser
- Erstellt am
Hi
Ich such eine Möglichkeit folgendes Szenario zu realisieren:
Prozess A besteht aus mehreren Threads, Prozess B aus einem einzelnen Thread (nur das letztere ist wichtig, also 1 Thread für Prozess B). Nun sollen zwischen beiden Prozessen Daten ausgetauscht werden.
Ablaufen soll das über ein Message System. Also Prozess B kann Prozess A irgendwelche Daten senden, und umgekehrt. Eine Message kann unterschiedlich groß sein und solche Sachen eben.
Etwas delikat ist allerdings die Verarbeitung dieser Messages, da das per Event-Handler geschehen soll, in einem einzigen Thread. Code macht das denke ich am besten deutlich:
Prozess B
Kommt eine Message soll die Ausführung von main() unterbrochen werden, und dafür der handler ausgeführt werden. Ist der Handler fertig, geht die Ausführung von main weiter.
Hab mich im Netz durch diverse Tutorials gelesen, aber noch nix wirklich passendes gefunden. Allgemein sind Multithreading und Interprozess-Wasauchimmer Sachen, mit denen ich mich noch nicht so weitgehend beschäftigt habe.
Ein weiterer Punkt wäre, dass ich den Thread von Prozess B solange in den Ruhestand schicken muss, bis eine Message ankommt. Also nicht nur sowas wie for(...) usleep(...), sondern, dass die Ausführung gänzlich stoppt. Idealerweise könnte der Thread das selbst veranlassen, und im Message-Handler auch wieder aufheben. Vielleicht kann man das ja irgendwie über die Scheduler-Einstellungen der POSIX-Threads machen?
Ich such eine Möglichkeit folgendes Szenario zu realisieren:
Prozess A besteht aus mehreren Threads, Prozess B aus einem einzelnen Thread (nur das letztere ist wichtig, also 1 Thread für Prozess B). Nun sollen zwischen beiden Prozessen Daten ausgetauscht werden.
Ablaufen soll das über ein Message System. Also Prozess B kann Prozess A irgendwelche Daten senden, und umgekehrt. Eine Message kann unterschiedlich groß sein und solche Sachen eben.
Etwas delikat ist allerdings die Verarbeitung dieser Messages, da das per Event-Handler geschehen soll, in einem einzigen Thread. Code macht das denke ich am besten deutlich:
Prozess B
Code:
int main()
{
tuwas();
tunochwas();
// usw.
}
void message_handler(void* message)
{
// event-handler für eingehende messages
}
Kommt eine Message soll die Ausführung von main() unterbrochen werden, und dafür der handler ausgeführt werden. Ist der Handler fertig, geht die Ausführung von main weiter.
Hab mich im Netz durch diverse Tutorials gelesen, aber noch nix wirklich passendes gefunden. Allgemein sind Multithreading und Interprozess-Wasauchimmer Sachen, mit denen ich mich noch nicht so weitgehend beschäftigt habe.
Ein weiterer Punkt wäre, dass ich den Thread von Prozess B solange in den Ruhestand schicken muss, bis eine Message ankommt. Also nicht nur sowas wie for(...) usleep(...), sondern, dass die Ausführung gänzlich stoppt. Idealerweise könnte der Thread das selbst veranlassen, und im Message-Handler auch wieder aufheben. Vielleicht kann man das ja irgendwie über die Scheduler-Einstellungen der POSIX-Threads machen?
Ray
Grand Admiral Special
- Mitglied seit
- 11.11.2001
- Beiträge
- 3.141
- Renomée
- 20
- Standort
- An der Spree
- Mein Laptop
- Kein Notbuch
- Prozessor
- Intel Core2Quad Q9650@3.8, AMD Ryzen 9 under test
- Mainboard
- DFI LANPARTY LT X48-T2R + MIPS DFI LANparty P35/X38/X48 Series Freezer Set Nickel
- Kühlung
- EK-Supreme
- Speicher
- 4 x 2 GB OCZ PC2 8500 C5 Reaper@500
- Grafikprozessor
- XFX 8800 GTS(G92) 512 + EK-FC8800 GT/GTS(g92)
- Display
- TFT HP w2408h, 1920x1200
- SSD
- Samsung 840 Pro 256 GB
- HDD
- 2 x WD Black 1TB
- Optisches Laufwerk
- Samsung SH-D163A, Samsung SH-S183A
- Soundkarte
- Creative X-FI Xtreme Gamer Fatality Pro
- Gehäuse
- Modified Lian Li PC201B
- Netzteil
- Seasonic S12 550W
- Betriebssystem
- Win7U-64
- Webbrowser
- FireFox
- Verschiedenes
- Thermochill PA120.3 Triple Radiator , Liang DDC , 11 years old mainboard, still running!
In C/C++ unter Windows könnte ich Dir das Ganze fast auswendig herunterbeten, unter Linux muss ich aber (noch) passen. Aber interessieren tut es mich schon, weshalb ich das hier auch poste. Es steht bald die Portierung einer Entwicklungsumgebung für Firmware-Projekte (2 bis n Prozesse, ein Prozess via DLL mit mehreren Threads) bei mir an.
Unter Windows läuft es mit mehreren Compilern (MS-VC++, Borland C++, Open Watcom) und seit neuestem auch als 64-Bit Version mit VC++ 8.0 Beta2.
Frage mich, ob ich zuerst Cygnus unter Windows heranziehe und dann erst den Schritt nach Linux durchziehen soll...
Idealerweise sollte alles als Gesamtpaket wahlweise unter Linux oder Windows laufen.
Eine plattformübergreifende Geschichte also. Mal schaun.
Ciao,
Ray
Unter Windows läuft es mit mehreren Compilern (MS-VC++, Borland C++, Open Watcom) und seit neuestem auch als 64-Bit Version mit VC++ 8.0 Beta2.
Frage mich, ob ich zuerst Cygnus unter Windows heranziehe und dann erst den Schritt nach Linux durchziehen soll...
Idealerweise sollte alles als Gesamtpaket wahlweise unter Linux oder Windows laufen.
Eine plattformübergreifende Geschichte also. Mal schaun.
Ciao,
Ray
Soweit geht das erstmal mit signals, allerdings lassen sich damit keine Daten übertragen. Man könnte zwar mit Signals signalisieren, dass irgendwo neue Daten verfügbar sind, nur kann man leider die Herkunft, also welcher Prozess ein Signal geschickt hat, afaik nicht bestimmen.
Bei einer begrenzten Anzahl von infragekommenden Quellen geht das, für mein Problem passt das aber nicht (bzw. weigere ich mich, sowas unsauberes zu implementieren - nein, in Wirklichkeit bin ich zu faul was zu schreiben, was zusammengeflickt wirkt und desswegen sowieso nochmal geändert werden müsste ).
Die Messages kann man auch per (named) pipes senden, hab dazu ja noch einen Thread aufgemacht. Da hab ich das Problem, dass ich eben so einen handler bräuchte der aufgerufen wird, wenn was neues angekommen ist. Nun könnte man das zwar per signal implementieren, aber weis dann eben nicht, welcher Prozess das signal geschickt hat, also von welchem Prozess neue Daten zu erwarten sind.
Bei einer begrenzten Anzahl von infragekommenden Quellen geht das, für mein Problem passt das aber nicht (bzw. weigere ich mich, sowas unsauberes zu implementieren - nein, in Wirklichkeit bin ich zu faul was zu schreiben, was zusammengeflickt wirkt und desswegen sowieso nochmal geändert werden müsste ).
Die Messages kann man auch per (named) pipes senden, hab dazu ja noch einen Thread aufgemacht. Da hab ich das Problem, dass ich eben so einen handler bräuchte der aufgerufen wird, wenn was neues angekommen ist. Nun könnte man das zwar per signal implementieren, aber weis dann eben nicht, welcher Prozess das signal geschickt hat, also von welchem Prozess neue Daten zu erwarten sind.
PuckPoltergeist
Grand Admiral Special
Die gewünschte Funktionalität sollten dir IPC-Messages liefern. Wenn ich mich jetzt richtig erinnere, blockiert msgrcv eh, wenn die Queue keine Nachrichten bereit hat, sprich der Prozess wird schlafen gelegt.
Ich brauch es aber nicht nach dem poll Prinzip, sondern nach dem Interrupt-Prinzip. So wie signal-handler. Geht das auch über IPC Messages? Hab da nämlich nix passendes gefunden...
Unschön wäre es das in mehreren Threads zu realisieren (von der Performance her), aber das wäre wahrscheinlich eine Möglichkeit... unschön desswegen, weil ich dann 2 Threads brauche wovon einer nur auf eingehende Nachrichten wartet. Außerdem müsste dann der 2. Thread pollen, ob beim 1. eine Nachricht angekommen ist.
So wirklich ideal ist das alles nicht.
Unschön wäre es das in mehreren Threads zu realisieren (von der Performance her), aber das wäre wahrscheinlich eine Möglichkeit... unschön desswegen, weil ich dann 2 Threads brauche wovon einer nur auf eingehende Nachrichten wartet. Außerdem müsste dann der 2. Thread pollen, ob beim 1. eine Nachricht angekommen ist.
So wirklich ideal ist das alles nicht.
PuckPoltergeist
Grand Admiral Special
Ich bin mir jetzt nicht mehr 100%ig sicher, da es auch schon wieder ein paar Jährchen her ist, seit ich intensiv mit IPC gearbeitet habe, aber ich glaube mich zu erinnern, dass msgsnd und msgrcv blockierend arbeiten. Da brauchst du also nix pollen, die Synchronisation das OS für dich.
Geht das bei Messages nicht auch wie bei Signalen? Sonst muss ich für jeden Prozess mindestens 2 Threads machen, und das wäre ja Verschwendung . Außerdem wird so jeder Prozess multithreaded, was die Sache auch nicht übersichtlicher macht.
PuckPoltergeist
Grand Admiral Special
Geht das bei Messages nicht auch wie bei Signalen? Sonst muss ich für jeden Prozess mindestens 2 Threads machen, und das wäre ja Verschwendung . Außerdem wird so jeder Prozess multithreaded, was die Sache auch nicht übersichtlicher macht.
Ich weiß jetzt nicht, was du mit "wie bei Signalen" meinst.
Das grundsätzlich Vorgehen ist folgendes:
Du erzeugst eine message-queue, egal von welcher Seite. Diese nimmst du mit dem anderen Prozess entgegen. Dann rufst du in dem Prozess, welcher die Nachricht empfangen soll, msgrcv auf. Liegt in der queue keine Nachricht vom passenden typ vor, so blockiert der Prozess. Sobald eine passende Nachricht eingeht, wird der Prozess dann wieder aufgeweckt.
Hier mal den Auszug aus dem manual:
If no message of the requested type is available and IPC_NOWAIT isn't specified in msgflg, the calling process is blocked until one of the following conditions occurs:
A message of the desired type is placed in the queue.
The message queue is removed from the system. In this case the system call
fails with errno set to EIDRM.
The calling process catches a signal. In this case the system call fails
with errno set to EINTR.
Beispiel:
Das Programm verzweigt automatisch zum handler, wenn ein Signal ankommt.
Code:
#include <stdio.h> /* standard I/O functions */
#include <unistd.h> /* standard unix functions, like getpid() */
#include <sys/types.h> /* various type definitions, like pid_t */
#include <signal.h> /* signal name macros, and the signal() prototype */
/* first, here is the signal handler */
void catch_int(int sig_num)
{
/* re-set the signal handler again to catch_int, for next time */
signal(SIGINT, catch_int);
/* and print the message */
printf("Don't do that");
fflush(stdout);
}
.
.
.
/* and somewhere later in the code.... */
.
.
/* set the INT (Ctrl-C) signal handler to 'catch_int' */
signal(SIGINT, catch_int);
/* now, lets get into an infinite loop of doing nothing. */
for ( ;; )
pause();
Das Programm verzweigt automatisch zum handler, wenn ein Signal ankommt.
PuckPoltergeist
Grand Admiral Special
Hat mit der IPC nicht wirklich etwas zu tun. Nimm Messages, dafür sind die schließlich da.
PuckPoltergeist
Grand Admiral Special
Ok, ich glaube, jetzt weiß ich, was du meinst. Das kannst du über FIFOs oder über Messages realisieren. Messages wären wahrscheinlich besser, weil die Prozess B automatisch schlafen legen, so er auf eine Nachricht warten muss. Die Unterbrechung des aktuellen Programmfluss kannst du mit Signalen machen. SIGUSR1 und SIGUSR2 würden sich dafür anbieten.
Wenn es dir auf Geschwindigkeit ankommt, musst du mal messen. FIFOs und Messages haben bei unterschiedlichen Nachrichtengrößen verschiedenes Verhalten.
Wenn es dir auf Geschwindigkeit ankommt, musst du mal messen. FIFOs und Messages haben bei unterschiedlichen Nachrichtengrößen verschiedenes Verhalten.
Na dann werd ich das so machen. Wie komm ich eigentlich an die struct ran, die die Senderpid enthält? Wenn du es nicht aus dem Kopf weist kann ich auch nachlesen, hab eine ganz brauchbare Seite zu signals gefunden.
PuckPoltergeist
Grand Admiral Special
man sigaction sollte dir da weiterhelfen
Nachtschicht
Admiral Special
Ja, meistens...ok danke, dürfte damit funktionieren.
Bei Signalen muss man bei jedem einzelnen System- oder lib-Call checken, ob die Funktion async-signal-safe ist, das ist noch eine Stufe über mt-safe (steht auf man page). Also so viele erlaubte calls gibt es nicht, aus dem Gedächtnis gehören read/write dazu, printf nicht. Auch der eigene Code muss jederzeit unterbrechbar sein.
Also praktisch kann man im Signalhandler nicht viel mehr tun als ein Flag setzen, das im "Vordergrundprogramm" gepollt wird.
Der richtige Weg geht über Socketkommunikation, mal auf die Schnelle ein Einstiegslink:
http://www.willemer.de/informatik/unix/unprsock.htm
Das(!) Buch ist von Stevens : "UNIX Network Programming, The Sockets Networking"
http://www.amazon.de/exec/obidos/ASIN/013490012X/302-6182816-5139223
Je nachdem, wie weit man es treiben will.
PuckPoltergeist
Grand Admiral Special
Wieso willst du für IPC mit aller Gewalt Sockets, sprich Mechanismen zur Netzwerkkommunikation verwenden? Schonmal daran gedacht, dass das einen zusätzlichen Overhead ins Programm bringt?
Nachtschicht
Admiral Special
Weil man das im professionellen Bereich nun mal so macht. Wenn im Vordergrund wirklich nur pause() läuft kann man natürlich im Signalhandler alles ausführen, nur meist ist das nicht so.Wieso willst du für IPC mit aller Gewalt Sockets, sprich Mechanismen zur Netzwerkkommunikation verwenden? Schonmal daran gedacht, dass das einen zusätzlichen Overhead ins Programm bringt?
Ein relativ einfacher und anschaulicher Weg (auf dem gleichen Rechner) ist die Kommunikation über ein File (z.B. /tmp/myfile), ser "client" schreibt etwas hinein, der "server" liest. Wenn der Server noch etwas anderes tun soll, dann benutzt man poll oder select (oder einen zweiten Thread) zum Warten auf den read-event (nicht ausprobiert, aber sollte funktionieren).
PuckPoltergeist
Grand Admiral Special
Weil man das im professionellen Bereich nun mal so macht.
Das glaube ich nicht, Tim!
Wenn im Vordergrund wirklich nur pause() läuft kann man natürlich im Signalhandler alles ausführen, nur meist ist das nicht so.
Ein relativ einfacher und anschaulicher Weg (auf dem gleichen Rechner) ist die Kommunikation über ein File (z.B. /tmp/myfile), ser "client" schreibt etwas hinein, der "server" liest. Wenn der Server noch etwas anderes tun soll, dann benutzt man poll oder select (oder einen zweiten Thread) zum Warten auf den read-event (nicht ausprobiert, aber sollte funktionieren).
Klar, und wenn der Client alle paar Minuten mal was an den Server schreibt, pollt der Server munter die ganze Zeit, weil wir ja auch sonst nichts sinnvolles mit der Rechenzeit anfangen können.
Nachtschicht
Admiral Special
Glaub, was du willst. Wie ich bereits geschrieben hatte, benutzt man poll() oder select() (RTFM! ). Wo geht da jetzt Rechenzeit verloren?Das glaube ich nicht, Tim!
Klar, und wenn der Client alle paar Minuten mal was an den Server schreibt, pollt der Server munter die ganze Zeit, weil wir ja auch sonst nichts sinnvolles mit der Rechenzeit anfangen können.
Hier ist ein interessanter Artikel zum Gebrauch von select() bei message queues:
http://linuxgazette.net/issue92/hawk.html
Falls die Funktion "msgqToFd(int msgq_id)" verfügbar ist, ist die Lösung einer socketbasierten ebenbürtig, die erste Variante mit dem timeout ist "ugly".
Zuletzt bearbeitet:
Ähnliche Themen
- Antworten
- 0
- Aufrufe
- 35K
- Antworten
- 67
- Aufrufe
- 4K
- Antworten
- 21
- Aufrufe
- 3K
- Antworten
- 46
- Aufrufe
- 8K
G