Schrift
[thread]13006[/thread]

fork stdout

Leser: 2


<< >> 10 Einträge, 1 Seite
Gast Gast
 2009-01-15 21:14
#118044 #118044
Hallo!

Eine Frage zu fork():
Ist es erlaubt, beide Prozesse (Parent und Child) nach "stdout" schrieben zu lassen?
Gast Gast
 2009-01-15 22:05
#118046 #118046
klar, warum nicht?
Dubu
 2009-01-16 00:26
#118050 #118050
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
Code: (dl )
1
2
3
4
5
6
7
8
$ perl -le '$num=0; if (fork) { while(1) { print "Elter: ", ++$num; sleep 1 } } else { while(1) { print "Kind: ", ++$num; sleep 1 } }'
Elter: 1
Kind: 1
Elter: 2
Kind: 2
Elter: 3
Kind: 3
^C
murphy
 2009-01-16 06:05
#118053 #118053
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
Erlaubt ist, was gefaellt. Allerdings kommt unter Umstaenden ziemlicher Salat heraus, wenn mehrere Prozesse gleichzeitig in einen Datenstrom schreiben. Es ist keinesfalls garantiert, dass die Ausgaben immer so ordentlich hintereinander stehen, wie bei Dubus Beispiel.
When C++ is your hammer, every problem looks like your thumb.
Gast Gast
 2009-01-16 10:09
#118057 #118057
Bei einer synkronisierten Ausgabe sind Threads besser, denn da kann man dafür sorgen, dass sie aufeinander warten, wenn es sein muß.
Gast Gast
 2009-01-16 11:33
#118068 #118068
Diese ergoogelte Seite hat mich veranlasst dazu nachzufragen:

How do I start a process in the background?
You could use

system("cmd &")

or you could use fork as documented in fork, with further examples in the perlipc manpage. Some things to be aware of, if you're on a Unix-like system:

STDIN, STDOUT and STDERR are shared
Both the main process and the backgrounded one (the ``child'' process) share the same STDIN, STDOUT and STDERR filehandles. If both try to access them at once, strange things can happen. You may want to close or reopen these for the child. You can get around this with opening a pipe (see open) but on some systems this means that the child process cannot outlive the parent.

Signals
You'll have to catch the SIGCHLD signal, and possibly SIGPIPE too. SIGCHLD is sent when the backgrounded process finishes. SIGPIPE is sent when you write to a filehandle whose child process has closed (an untrapped SIGPIPE can cause your program to silently die). This is not an issue with system("cmd&").

Zombies
You have to be prepared to ``reap'' the child process when it finishes

$SIG{CHLD} = sub { wait };

See Signals for other examples of code to do this. Zombies are not an issue with system("prog &").

Source: Perl FAQ: System Interaction
Copyright: Copyright (c) 1997 Tom Christiansen and Nathan Torkington.


Link darf ich vermutlich als Gast keinen einfügen.
renee
 2009-01-16 12:00
#118070 #118070
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Gast+2009-01-16 10:33:12--
Link darf ich vermutlich als Gast keinen einfügen.


Richtig. Du kannst aber den Link ohne das führende "http:///" posten.
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
murphy
 2009-01-17 03:19
#118113 #118113
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
Gast+2009-01-16 09:09:56--
Bei einer synkronisierten Ausgabe sind Threads besser, denn da kann man dafür sorgen, dass sie aufeinander warten, wenn es sein muß.


Prozesse koennen ebenfalls aufeinander warten. Das ist also kein Argument fuer Threads.
When C++ is your hammer, every problem looks like your thumb.
Gast Gast
 2009-01-17 16:06
#118125 #118125
Bin ohne "fork" besser zurecht gekommen.
Das Skript starte ich in einer Konsole: gibt es eine Möglichkeit das Schließen der Konsole (mit Klick Kreuz rechts oben) abzufangen?




sub write_to_file {
my $traffic = shift;
my @date = localtime();
my $day = $date[3];
my $month = $date[4] + 1;
my $year = $date[5] + 1900;
open( my $out, '>', $file ) or die "$!";
print $out "$day:$month:$year:$traffic\n";
close( $out );
}

Diese Subroutine gehört zum ( hoffentlich ) folgenden Skript.
Gast Gast
 2009-01-17 16:07
#118126 #118126
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#!/usr/bin/perl
use warnings;
use strict;
use File::Spec::Functions;


my $dir = '/home/mm/.t_m';
my $name = 'naviga3';
my $max_MB = 95;

mkdir( $dir ) or die "$!" if ! -d $dir;
my $file = catfile( $dir, $name );


sub count_traffic {
        my $dev = '/proc/net/dev';
        my $gesamt = 0;
        my $traffic = 0;
        my $summe = 0;
        my $mb_traffic=0;
        my @date = localtime();
        my $day = $date[3];
        my $month = $date[4] + 1;
        my $year = $date[5] + 1900;
        my $pidofpppd;
        
        if ( ! -f $file ) {
                open( my $fh, '>', $file ) or die "$!";
                        print $fh "$day:$month:$year:$traffic\n";
                close( $fh );
        }
        
        open( my $in, '<', $file ) or die "$!";
        while ( <$in> ) {
                $gesamt = $1 if /^$day:$month:$year:(\d+)$/;
        }
        close( $in );
        
        chomp( $pidofpppd = `pidof pppd` );
        kill 15, $pidofpppd if $pidofpppd;
        system( "wvdial &" );

        sub catch_signal { my $pidofwvdial = `pidof wvdial`; kill( 15, $pidofwvdial ); };
        local $SIG{INT} = \&catch_signal;
        local $SIG{QUIT} = \&catch_signal;
        local $SIG{KILL} = \&catch_signal;
        local $SIG{TERM} = \&catch_signal;

        while ( 1 ) {
                chomp( $pidofpppd = `pidof pppd` );
                last if $pidofpppd;
                select( undef, undef, undef, 0.25 );
        }

        while ( 1 ) {
                open( my $proc_net, '<', $dev ) or die "$!";
                while ( <$proc_net> ) {
                        if ( $_ =~ /^\s*ppp0:\s+(\d+)(?:\s+\d+){7}\s+(\d+)(?:\s+\d+){7}\s*$/ )
                                {
                                my $summe = $1 + $2;
                                $traffic = $gesamt + $summe;
                                $mb_traffic = $traffic / 1048576;
                                printf "%.2f\n", $mb_traffic;
                                my @d = localtime();
                                if ( $d[3] != $day ) {
                                        $summe=0;
                                        $gesamt=0;
                                        $traffic=0;
                                }
                                if ( $mb_traffic > $max_MB ) {
                                        $pidofpppd = `pidof pppd`;
                                        kill 15, $pidofpppd;
                                        #write_to_file( $traffic );
                                        exit;
                                }
                        }
                }
                close( $proc_net );
                select( undef, undef, undef, 0.25 );
                chomp( my $pidofpppd = `pidof pppd` );
                last if ! $pidofpppd;
        }
        END { write_to_file( $traffic ); };
}

count_traffic();
<< >> 10 Einträge, 1 Seite



View all threads created 2009-01-15 21:14.