Thread Entkoppelung zweier Prozesse mittels FIFO (6 answers)
Opened by fibbs at 2008-07-01 11:55

fibbs
 2008-07-01 11:55
#111714 #111714
User since
2008-06-30
1 Artikel
BenutzerIn
[Homepage] [default_avatar]
Hallo Community!

Ich verzweifle gerade an einem Problem, zu dem ich zunächst erklären möchte, was ich eigentlich bezwecke:

Ich habe ein System welches Daten sammelt und ein scheduling durchführt. Gewisse Events müssen an ein anderes System übermittelt werden, was eine zeitlang dauert. Das System ist so konzipiert, dass es auf Verzögerungen im Scheduling empfindlich reagiert, so dass hier eine Art Entkoppelung stattfinden muss.

Ich möchte nun also einen Daemon haben, der auf eine named pipe lauscht und Daten, die dort hineintröpfeln verarbeitet. Auf sendender Seite wird pro Event ein Script ausgeführt, welches die Zeile mit den Daten in den Fifo kippt. Der Sender soll immer sofort weiterlaufen ohne sich weiter um die Daten zu kümmern, der Empfänger (Daemon) hat nun ausreichend Zeit, die Queue abzuarbeiten.

Soweit die Theorie, nur leider habe ich das Problem, dass mein Daemon zwar arbeitet, aber nach dem Empfang der ersten Zeile an Daten auf 100% CPU-Last geht und von dort nicht mehr herunterkommt. Den Fifo nach dem Erhalt jeder Zeile zu schließen und erneut zu öffnen würde zwar helfen, ist aber nicht Sinn der Sache, da ich dann keine Entkoppelung mehr hätte.


Ich würde mich sehr freuen, wenn mir von Euch jemand einen Tritt in die richtige Richtung geben könnte.



################# Daemon-Script #####################
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#!/usr/bin/perl -w

use constant FIFOPATH => "/tmp/fifo-demo";
use POSIX qw(mkfifo);
use Fcntl qw(O_RDONLY);
use Sys::Syslog qw( :DEFAULT setlogsock);

# catch signals to die gracefully
$SIG{'TERM'} = 'handler';
$SIG{'INT'} = 'handler';

# syslog
sub do_syslog {
        my $msg = shift;
        setlogsock('unix');
        openlog($0,'','user');
        syslog('info',"$msg");
        closelog;
}


sub handler {
    my $signal = shift;    # signal-nummer besorgen
    $SIG{'TERM'} = 'handler';   # reinstall sig-handler
    $SIG{'INT'} = 'handler';   # reinstall sig-handler

    &do_syslog ("Signal: SIG$signal caught!");
    unlink(FIFOPATH);
    exit 0;
}

sub do_notification {
        my $string = shift;
        &do_syslog($string);
        # instead of this 'sleep' here should be some intelligent code to
        # do magic stuff with the data we got from uncle fifo.
        sleep 5;
}

########################### MAIN ################################


unlink(FIFOPATH);
mkfifo(FIFOPATH, 0666) or die "can't create FIFO: $!\n";

sysopen(FIFOFD, FIFOPATH, O_RDONLY) or die "can't read: $!\n";

#my $fifostring = "";
#while (1) {
#    if (sysread(FIFOFD, $fromfifo, 1) == 1) {
#       if ($fromfifo eq "\n") {
#               &do_notification($fifostring);
#               $fifostring = "";
#       } else {
#               $fifostring .= $fromfifo;
#       }
#    }
#}

# easyer reading line-by-line
while (1) {
        while (<FIFOFD>) {
                &do_notification($_);
        }
}



################# Client-Script ####################
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/perl -w
# fifo-client.pl -- Sendet Auftraege in eine FIFO hinein.

use strict;
use Data::Dumper;

my $fifo = "/tmp/fifo-demo";
my $string = shift;


#sysopen(FIFOFD, FIFOPATH, O_WRONLY) or die "can't write: $!\n";
open (FIFOFD, ">$fifo") or die "could not open fifo: $!\n";
print FIFOFD "$string\n";
close (FIFOFD);

View full thread Entkoppelung zweier Prozesse mittels FIFO