2015-10-08 12 views
7

Ich versuche, ein einfaches Skript zu schreiben, das Threads verwendet und eine Variable freigibt, aber ich möchte diese Variable nicht für das gesamte Skript global machen. Unten ist ein vereinfachtes Beispiel.Freigeben einer Thread-Variablen, ohne sie global zu machen (Perl)

use strict; 
use warnings; 
use threads; 
use threads::shared; 

my $val:shared; 

# Create threads 
for my $i (1 .. 5) { 
    threads->create(\&do_something, $i); 
} 

# Wait for all threads to complete 
map { $_->join(); } threads->list(); 

# $val is global to the script so this line will work! 
print "VAL IS: $val\n"; 

sub do_something { 
    my $i = shift; 
    print "Doing something with thread $i!\n"; 

    { 
     lock $val; 
     $val = "SOMETHING IS $i"; 
     print "$val\n\n"; 
    } 
} 

Ausgang:

1 etwas mit Gewinde tun! ETWAS IST 1

Etwas mit Thread 2 tun! SOMETHING IS 2

Etwas mit Thread 3 tun! SOMETHING IS 3

Etwas mit Thread 4 tun! ETWAS IS 4

Etwas mit Gewinde 5 tun! ETWAS 5

VAL: Etwas 5


Wie kann ich diesen Effekt zu erzielen, ohne $val zugänglich für die ganze Skript zu machen? Mit anderen Worten, wie kann ich es so machen, dass der Versuch zum Drucken VAL IS: $val schlägt fehl, aber die Variable wird weiterhin erfolgreich von den Threads geteilt werden?


ich es so nicht definieren:

# Create threads 
for my $i (1 .. 5) { 
    my $val:shared; 
    threads->create(\&do_something, $i); 
} 

Oder ich bekomme:

Globales Symbol "$ val"

explizites Paket erfordert

Was ist der richtige Weg, um eine gemeinsame Variable lexikalisch zu definieren?

+0

Es sei denn, Sie es in vorbei sind, wie könnte ein Thread beide gemeinsam genutzt werden (global) und nicht global? Offenbar möchten Sie eine Ebene für Ihren Bereich erstellen. Haben Sie auch versucht, 'our ($ val);'? – vol7ron

+1

Randnotiz, 'map {$ _-> join(); } threads-> list(); '=>' $ _-> join() für threads-> list(); 'um deine Absichten klar zu machen. –

+0

@ Сухой27, danke das ist ein bisschen klarer. – tjwrona1992

Antwort

4

Übergeben Sie einen Verweis darauf als Argument.

sub do_something { 
    my ($id, $lock_ref) = @_; 
    print("$id: Started\n"); 
    { 
     lock $$lock_ref; 
     print("$id: Exclusive\n"); 
     sleep(1); 
    } 
    print("$id: done.\n"); 
} 

{ 
    my $lock :shared; 
    for my $id (1..5) { 
     async { do_something($id, \$lock); }; 
    } 
} 

oder Umfang es so nur die Arbeiter subs kann es sehen.

{ 
    my $lock :shared; 

    sub do_something { 
     my ($id) = @_; 
     print("$id: Started\n"); 
     { 
     lock $lock; 
     print("$id: Exclusive\n"); 
     sleep(1); 
     } 
     print("$id: done.\n"); 
    } 
} 

for my $id (1..5) { 
    async { do_something($id); }; 
} 
4

Sie können den Umfang der gemeinsamen Variablen begrenzen (vergewissern Sie sich, dass Perl-Variable vor Thread-Erzeugung geteilt sieht),

# .. 
{ 
    my $val:shared; 
    sub do_something { 
     my $i = shift; 
     print "Doing something with thread $i!\n"; 

     { 
      lock $val; 
      $val = "SOMETHING IS $i"; 
      print "$val\n\n"; 
     } 
    } 
} 

# Create threads 
for my $i (1 .. 5) { 
    threads->create(\&do_something, $i); 
} 

# ... 
Verwandte Themen