Schrift
[thread]8825[/thread]

Kill von Threads

Leser: 3


<< >> 5 Einträge, 1 Seite
wenze
 2007-03-09 16:09
#74885 #74885
User since
2006-06-15
29 Artikel
BenutzerIn
[default_avatar]
Hi,

jetzt bin ich am verzweifeln. Folgende Zeilen bringen mir ein Segmentation fault. Mir reicht schon wenn ich wüßte, wo ich weitersuchen soll.

Und nun zu dem Skript:

Ich muss eine Langzeitsicherung schreiben. Bitte nicht nach dem Sinn fragen, ich habe es aufgegebe und schreibe einfach jetzt nur.

Ich habe mein Verzeichnis mit meinen Datenbankdateinen, mein Skript sucht nun nach Dateien größer X und und erstellt einen "tar -czvf ...". Jeder tar wird dann in einem eigenen Thread ( max. Y) gestartet.

Wenn einer von den gestarteten tars abbricht wird ein kill an die Prozessgruppe gesendet. Das "Hauptprogramm" ignoriert das Signal und ruft den Handler auf, der noch einmal ein kill sendet und den Rest wieder bereinigt (Dateien löschen ect.)

Sobald ich den kill hander aktiviere knallt es.

Code: (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
local $SIG{HUP} = 'IGNORE';
$SIG{HUP} = \&SIGKILL_handler;

while ( $#todo >= 0 && $result == 0) {
last if($result > 0);
my $cmd = pop(@todo);
$sem->down(); # nur n Tasks gleichzeitig
if ( $result == 0) {
my $thread = threads->new(
\&Task,
$cmd, # neuen Thread erzeugen
);
}
}

#-------------------------------------------------------------------------
sub Task {
my (
$cmd, # Parameter
) = @_;
my $id = threads->self->tid;
$thread_run++;
$result += system ($cmd)/256;;
if ($debug == 1) { print " Return: $result \n\n"; }
$sem->up();
$thread_run--;
printf "Thread %02d: fertig.\n", $id;
if ($result >0){print "\n\n Fehler !!!!!!!!\n\n";
kill ("HUP", -$$);
}

}

#-------------------------------------------------------------------------
sub SIGKILL_handler {
print "SIG_KILL\n";
kill ("HUP", -$$);
}


Danke für jeden Tipp
bloonix
 2007-03-09 19:24
#74886 #74886
User since
2005-12-17
1615 Artikel
HausmeisterIn
[Homepage]
user image
Hallo,

[quote=wenze,09.03.2007, 15:09]Sobald ich den kill hander aktiviere knallt es.[/quote]
was meinst du damit? Wie aktivierst du ihn? Sendest du testweise ein
HUP an den Prozess oder ist die Zuweisung

Code: (dl )
1
2
local $SIG{HUP} = 'IGNORE';
$SIG{HUP} = \&SIGKILL_handler;


zwischenzeitlich auskommentiert und wenn du es einkommentierst,
knallt es? Zudem verstehe ich nicht ganz, weshalb du $SIG{HUP}
zuerst 'IGNORE' zuweist und direkt danach eine Subref?!

Gruss,
opi\n\n

<!--EDIT|opi|1173464826-->
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.
topeg
 2007-03-09 20:35
#74887 #74887
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Ich hätte das ganze etwas anders gemacht. Da keine Werte zurückgeben werden, würe ich forken und die Prozesse mit $SIG{CHLD} überwachen.
So ungefähr:
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
#!/usr/bin/perl

use strict;
use warnings;
use POSIX ':sys_wait_h';

my $anzahl=5;
my @kinder=map{$_=0}(0..$anzahl);
my $cmd="sh -c 'sleep %u'";

sub ende()
{
  $SIG{CHLD}='IGNORE';
  kill(9,grep{$_>0}@kinder);
  exit;
}
$SIG{INT}=\&ende;
$SIG{HUP}=\&ende;
$SIG{QUIT}=\&ende;

sub watch_childs()
{
  for my $pid (@kinder)
  {
   if($pid!=0)
   {
    if(waitpid( $pid, WNOHANG )==$pid)
    {
     print "Prozess $pid beendet";
     $pid=0;
     my $status=$?/256;
     if($status!=0)
     {
      print " aber ein Fehler ist aufgetreten! ($status)\n";
      $SIG{CHLD}='IGNORE';
      kill(9,grep{$_>0}@kinder);
      die "Beende mich wegen Fehler in einem Kindprozess ($pid)!\n";
     }
     else
     { print " und kein Fehler ist aufgetreten.\n"; }
    }
    else
    { print "Prozess $pid läuft noch\n"; }
   }
  }
}
$SIG{CHLD}=\&watch_childs;

my $cnt=0;
for my $pid (@kinder)
{
  $cnt++;
  $pid=fork();
  exec(sprintf($cmd,$cnt*2)) unless($pid);
}

# mach was anderes...
while(waitpid( -1, WNOHANG ) != -1)
{
  sleep(3);
  print "Warte\n";
}
\n\n

<!--EDIT|topeg|1173465610-->
topeg
 2007-03-09 21:20
#74888 #74888
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Ich habe den Code so angepasst, daß er ungefähr das macht was deiner machen soll. :-)
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
87
88
#!/usr/bin/perl

use strict;
use warnings;
use POSIX ':sys_wait_h';


my $anzahl=5;
my @kinder=map{$_=0}(0..$anzahl);
my @cmds=("sleep 20",
          "sleep 10",
          "sleep 30",
          "sleep 10",
          "sleep 20",
          "sleep 30",
          "sleep 20",
          "sleep 10",
          "sleep 30",
          "sleep 10",
          "sleep 20",
          "sleep 30",
          "sleep 20",
          "sleep 10",
          "sleep 30");

sub ende()
{
  $SIG{CHLD}='IGNORE';
  kill(9,grep{$_>0}@kinder);
  exit;
}
$SIG{INT}=\&ende;
$SIG{HUP}=\&ende;
$SIG{QUIT}=\&ende;

sub watch_childs()
{
  for my $pid (grep{$_>0}@kinder)
  {
   if(waitpid( $pid, WNOHANG )==$pid)
   {
    print "Prozess $pid beendet";
    my $status=$?/256;
    if($status!=0)
    {
     print " aber ein Fehler ist aufgetreten! ($?)\n";
     $SIG{CHLD}='IGNORE';
     kill(9,grep{$_>0}@kinder);
     die "Beende mich wegen Fehler in einem Kindprozess ($pid)!\n";
    }
    else
    { print " und kein Fehler ist aufgetreten.\n"; }
    # nächsten Befehl staren
    $pid=0;
    if(@cmds)
    {
     my $cmd=shift(@cmds);
     $pid=fork();
     exec($cmd) unless($pid);
    }
   }
  }
}
$SIG{CHLD}=\&watch_childs;

for my $pid (@kinder)
{
  my $cmd=shift(@cmds);
  $pid=fork();
  exec($cmd) unless($pid);
}

# mach was anderes...
my $ex=1;
while($ex)
{
  sleep(3);
  $ex=0;
  for my $pid (grep{$_>0}@kinder)
  {
   if(kill(0,$pid))
   {
    print "Prozess $pid läuft noch. \n";
    $ex=1;
   }
  }
  print "Es warten noch ".@cmds." Befehle auf Ausführung.\n";
}
\n\n

<!--EDIT|topeg|1173468732-->
wenze
 2007-03-12 14:08
#74889 #74889
User since
2006-06-15
29 Artikel
BenutzerIn
[default_avatar]
@topeg

Danke,

ich schau mal nach ob ich es so mache.


@opi

Mein "Hauptprogramm" soll ja weiter laufen, deshalb ignor und das sub. Stand im Buch so..
<< >> 5 Einträge, 1 Seite



View all threads created 2007-03-09 16:09.