Toon posts:

[perl] Vanuit thread updaten in main-thread

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben bezig met een perl programma wat met threads werkt.

Een thread moet kunnen schrijven in een lijstje in de mainthread, en andere threads moeten deze waarden ook weer kunnen lezen.

Nu is het punt dat als je in een thread iets wijzigt, dan is dat binnen die thread wel gewijzigd, maar voor de andere threads niet.

Perl:
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
#!/usr/bin/perl -w

# Basis
use strict;
use warnings;
use Thread;

# lijst met clients
our %clients;
$clients{ "client_1" } = "init";

my $thrd = new Thread( \&process_request, \%clients, "client_1" );
$thrd->join(); # wachten
$thrd = new Thread( \&process_request, \%clients, "client_1" );
$thrd->join();

# process
sub process_request {
    # args
    my $clientlist = shift;
    my $id = shift;

    logw( "Started thread" );
    logw( $$clientlist{ $id } );
    lock( $$clientlist{ $id } );
    {
        $$clientlist{ $id } = "wijzig";
    }
    logw( $$clientlist{ $id } );
    logw( "Exitting thread" );
}

sub logw {
    my $message = shift;
    print $message ."\n";
}


En dat geeft de output:
Text output:
1
2
3
4
5
6
7
8
Started thread
init
wijzig
Exitting thread
Started thread
init
wijzig
Exitting thread


Terwijl dat zou moeten zijn:
Text output:
1
2
3
4
5
6
7
8
Started thread
init
wijzig
Exitting thread
Started thread
wijzig
wijzig
Exitting thread


Of te wel het werkt niet :|.
Ik heb van alles geprobeerd met het veranderen van references e.d., maar dat mocht niet baten.
Heeft iemand hier een oplossing voor?

Verwijderd

Misschien dat je hier iets aan hebt

Locks on variables only affect lock calls--they do not affect normal access to a variable. (Locks on subs are different, and covered in a bit.) If you really, really want locks to block access, then go ahead and tie them to something and manage this yourself. This is done on purpose. While managing access to variables is a good thing, Perl doesn't force you out of its living room...

http://search.cpan.org/~jhi/perl-5.8.1/lib/Thread.pm

Verwijderd

Topicstarter
Verwijderd schreef op 16 October 2003 @ 18:34:
Misschien dat je hier iets aan hebt

Locks on variables only affect lock calls--they do not affect normal access to a variable. (Locks on subs are different, and covered in a bit.) If you really, really want locks to block access, then go ahead and tie them to something and manage this yourself. This is done on purpose. While managing access to variables is a good thing, Perl doesn't force you out of its living room...

http://search.cpan.org/~jhi/perl-5.8.1/lib/Thread.pm
Ja, dat is ook de reden dat de lock daar uitgevoerd wordt, zodat niet verschillende threads het zelfde element van de hash zullen oppakken.

Maar voor het probleem opzich kan de lock helemaal weg, ook dan werkt het niet.

Verwijderd

Ha Wietse,

Ik heb de oplossing gevonden. Je moet niet Thread gebruiken, maar threads::shared. dan geef je aan dat je een shared variabele hebt en dan gaat 't als 'n dijk:

Perl:
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
#!/usr/bin/perl -w

# Basis
use strict;
use warnings;
use threads;
use threads::shared;

use IO::Handle;

STDOUT->autoflush(1);

# lijst met clients
our %clients : shared;
$clients{ "client_1" } = "init";

my $thrd = new threads( \&process_request, \%clients, "client_1" );
$thrd->join(); # wachten

logw("");
$thrd = new threads( \&process_request, \%clients, "client_1" );
$thrd->join();

# process
sub process_request {
    # args
    my $clientlist = shift;
    my $id = shift;

    logw( "Started thread" );
    logw( "-> " . $$clientlist{ $id } );
#    lock( $$clientlist{ $id } );
    {
        $$clientlist{ $id } = "wijzig";
    }
    logw( "-> " . $$clientlist{ $id } );
    logw( "Exitting thread" );
}

sub logw {
    my $message = shift;
    print $message ."\n";
}


Succes!

Die lock kan er niet meer op de huidige manier in. dan krijg je deze error:
code:
1
thread failed to start: lock can only be used on shared values at threadtest.pl line 32.


Maak je er echter $$clientlist van dan krijg je dit:
code:
1
thread failed to start: Not a SCALAR reference at threadtest.pl line 32.


Neergezet als $clientlist van dan krijg je geen meldingen.. het lijkt erop of hij dan het goede locked...

edit:
Output:

code:
1
2
3
4
5
6
7
8
9
Started thread
-> init
-> wijzig
Exitting thread

Started thread
-> wijzig
-> wijzig
Exitting thread

[ Voor 43% gewijzigd door Verwijderd op 16-10-2003 20:58 ]