IPC unter Linux

Benutzeravatar
willi4willi
Lazarusforum e. V.
Beiträge: 155
Registriert: Sa 1. Nov 2008, 18:06
OS, Lazarus, FPC: Windows, Linux (debian) / Lazarus 3.2 / FPC 3.2.2
CPU-Target: i386, win64, arm

IPC unter Linux

Beitrag von willi4willi »

Hallo!

Ich möchte zwischen Programmen Daten mittels IPC austauschen. Unter Windows klappt der folgende Code wunderbar nur nicht unter Linux:

Code: Alles auswählen

 
unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, simpleipc, FileUtil, Forms, Controls, Graphics, Dialogs,
  StdCtrls;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Test: TEdit;
    SendMessage: TButton;
    ClientStart: TButton;
    Serverstart: TButton;
    Memo1: TMemo;
    SimpleIPCClient1: TSimpleIPCClient;
    SimpleIPCServer1: TSimpleIPCServer;
    procedure SendMessageClick(Sender: TObject);
    procedure ClientStartClick(Sender: TObject);
    procedure ServerstartClick(Sender: TObject);
    procedure SimpleIPCServer1Message(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.SimpleIPCServer1Message(Sender: TObject);
var s: String;
begin
  s := SimpleIPCServer1.StringMessage;
  Memo1.Lines.Add('--> '+s);
end;
 
procedure TForm1.SendMessageClick(Sender: TObject);
begin
  if SimpleIPCClient1.Active
    then SimpleIPCClient1.SendStringMessage(Test.Text)
    else Memo1.Lines.Add('Erst den Client starten!');
end;
 
procedure TForm1.ClientStartClick(Sender: TObject);
begin
  Memo1.Lines.Add('Starte Client');
  SimpleIPCClient1.ServerID := 'test';
  if SimpleIPCClient1.ServerRunning
    then SimpleIPCClient1.Connect
    else Memo1.Lines.Add('kein Server!');
end;
 
procedure TForm1.ServerstartClick(Sender: TObject);
begin
  Memo1.Lines.Add('Starte Server');
  SimpleIPCServer1.ServerID := 'test';
  SimpleIPCServer1.Global := True;
  SimpleIPCServer1.StartServer;
end;
 
end.
 
 


Der Start von Server und Client funktioniert offensichtlich. Der Server scheint aber unter Linux nichts zu empfangen.
Es kommt keine Fehlermeldung hoch.

Ist das bei Euch auch so? Hat jeman eine Ahnung warum?

Meine Umgebung
- Windows 8.1: Lazarus 1.2.4, FPC 2.6.4
- Linux Debian GNU/Linux 7.7 (wheezy): Lazarus 1.2.4, FPC 2.6.4 (i386-gtk2)


Viele Grüße

Willi4Willi
 

Viele Grüße

Willi4Willi

------------

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: IPC unter Linux

Beitrag von theo »

Unter Linux muss man zusätzlich pollen.
Füge diesen Code hinzu:

Code: Alles auswählen

procedure TForm1.ApplicationIdle(Sender: TObject; var Done: Boolean);
begin
  if SimpleIPCServer1.Active then SimpleIPCServer1.PeekMessage(0,true);
end;
 
procedure TForm1.FormCreate(Sender: TObject); //<- Form OnCreate Event
begin
  Application.OnIdle:=@ApplicationIdle;
end;     

Benutzeravatar
willi4willi
Lazarusforum e. V.
Beiträge: 155
Registriert: Sa 1. Nov 2008, 18:06
OS, Lazarus, FPC: Windows, Linux (debian) / Lazarus 3.2 / FPC 3.2.2
CPU-Target: i386, win64, arm

Re: IPC unter Linux [gelöst]

Beitrag von willi4willi »

Hey super! So funktioniert' s.

Danke Theo. Du bist der Beste!
 

Viele Grüße

Willi4Willi

------------

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: IPC unter Linux

Beitrag von mschnell »

theo hat geschrieben:Füge diesen Code hinzu:...


=> 100% CPU Auslastung auf dem Rechner. Vermutlich (Zeitscheiben) nur noch höchsten 50 % Performance für die andere Applikation.

Oder täusche ich mich da ?

Kann SimpleIPC nicht z.B. Pipes mit blocking read o.ä ?

-Michael

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: IPC unter Linux

Beitrag von theo »

Application.OnIdle ?

magnetron
Beiträge: 44
Registriert: Di 4. Nov 2014, 14:04

Re: IPC unter Linux

Beitrag von magnetron »

Hallo,

ich habe das so gelöst:

Code: Alles auswählen

   tmr_receive.Enabled := false;
   repeat
     IF FIPCServer.Active then
       vReceived := FIPCServer.PeekMessage(10, true);
     Application.ProcessMessages;
     IF not FIPCactive then break;
   until not vReceived;
   tmr_receive.Enabled := true


Das ganze läuft mit einem timer (den ich auf 50msec gesetzt habe).
Eventuell - wenn OnIdle benutzt wird - hilft es den timeout zu erhöhen, nicht auf 0 zu lassen ? Nur eine Vermutung.

Grüße Stefan

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: IPC unter Linux

Beitrag von theo »

magnetron hat geschrieben:Eventuell - wenn OnIdle benutzt wird - hilft es den timeout zu erhöhen, nicht auf 0 zu lassen ? Nur eine Vermutung.

Nö, dann wird nur länger gewartet und damit der Hauptthread wirklich eine gewisse Zeit blockiert.
Ansonsten ist das mal wieder ein "mschnell" Problem.... :wink:

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: IPC unter Linux

Beitrag von mschnell »

theo hat geschrieben:Application.OnIdle ?

... wird soweit ich weiß immer dann und immer wieder aufgerufen, wenn die Application gerade nichts besseres zu tun hat, also quasi immer. => 100 % CPU

-Michael

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: IPC unter Linux

Beitrag von theo »

mschnell hat geschrieben:
theo hat geschrieben:Application.OnIdle ?

... wird soweit ich weiß immer dann und immer wieder aufgerufen, wenn die Application gerade nichts besseres zu tun hat,

Genau, und wo ist das Problem?
Nein, halt! Ich möchte es gar nicht wissen. :wink:

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: IPC unter Linux

Beitrag von mschnell »

theo hat geschrieben:Genau, und wo ist das Problem?

Wie vom OP beschrieben ist da ja nicht nur eine Applikation, sondern zwei. und wenn die eine alle CPU-Zeit verbrät, die sie bekommen kann, ist für die zweite nur noch halb so viel CPU Zeit verfügbar, wie wenn die andere keine CPU-Zeit vom Betriebssystem anfordern würde. Die andere Applikation läuft also halb so schnell wie sie könnte. (Annahme: nur diese beiden Applikationen sind hier relevant, wenn der Rechner außerdem noch etwas ganz anderes tun soll wird es um so schlimmer.)

-Michael

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: IPC unter Linux

Beitrag von theo »

Wieso schreibst du immer so ein überflüssiges Zeug?
Hast du deine Behauptungen überprüft?
Was sagt dein Systemmonitor?

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: IPC unter Linux

Beitrag von mschnell »

theo hat geschrieben:Hast du deine Behauptungen überprüft?

Dann hätte ich nicht "Soweit ich weiß" dazu geschrieben.

Wenn Du weißt, dass es anders ist (Polling per "Application.OnIdle" also nicht 100% CP erzeugt), hättest Du das ja klar sagen können.

-Michael

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: IPC unter Linux

Beitrag von theo »

Ich finde man sollte solche Behauptungen überprüfen, bevor man sie in die Welt setzt.
Es hat ja niemand danach gefragt, du hast diese Unwahrheit aus eigenem Antrieb verbreitet.

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: IPC unter Linux

Beitrag von mschnell »

theo hat geschrieben: du hast diese Unwahrheit aus eigenem Antrieb verbreitet.

Eigentlich habe ich mein Unwissen dokumentiert und somit eine Frage gestellt (die bisher keiner beantwortet hat).

Ich probier's mal selber aus....

-Michael

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: IPC unter Linux

Beitrag von mschnell »

OK. Ich hab's ausprobiert

1) Theo hat recht es erzeugt keine 100 % CPU-Last.

2) Theo hat Unrecht, es ist für diesen Zweck nicht - zumindest nicht so ohne weiteres - anwendbar.

Der Grund für beides ist, dass das Event Application.OnIdle nicht permanent aufgerufen wird (wie ich vermutet hatte) sondern nur einmal pro von der Event-Queue bearbeitetes Event. Wenn die Applikation also einfach nur läuft und keine anderen Events auftretet (z.B. man mit der Maus über das Fenster streicht), wird Application.OnIdle nie aufgerufen.

-Michael

Antworten