http://qs321.pair.com?node_id=944454


in reply to any module with streaming pipe implementation for use with threads

Hi Rohan,

I haven't used threads in quite a while now, but after reading through your code I do have a couple comments/observations to make. Take them with a grain of salt.

First of all, are you absolutely certain that you need to roll your own shared stack? Other than controlling the size of the stack, and your 'phases', it looks to me like you could do the same using threads::shared. In fact, it looks like you started that approach. It may be that you are overengineering the project.

Secondly, I don't believe your communication object, $pipe1, is going to be shared between the two threads. If I recall my perl threading model, each thread receive a copy of the interpreter, with data as-of the creation of the thread. Once that split has been done, they don't share any relationship with each other.

Here's something that I whipped up real fast. No doubt the locking mechanism isn't correct, but maybe it'll point you towards the correct location:

use strict; use warnings; use threads; use threads::shared; my @stack: shared; my $thr = threads->create(\&thr2); threads->create(\&thr1)->detach; threads->create(\&thr1)->detach; $thr->join; sub get { threads->yield while scalar @stack == 0; lock(@stack); pop @stack; } sub put { my $val = shift; lock(@stack); push @stack,$val; } sub thr1 { put($_) for 1..500; } sub thr2 { my $cnt; my $val; while ($val = get()) { $cnt++; print "$val ($cnt)\n"; } }

I can see a few issues with my code, especially if there are multiple getters and putters running at the same time. But you can serialize those operations, in a very brute force kind of way, but creating some shared scalars (eg: $get_in_progress) and locking those.

Edit: changed code to do a little more work.
Editx2: do what BrowserUK said.

mr.nick ...