Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
Have you ever heard of the concept of a reduced testcase?

I'm sorry... when I did the work I was trying to find what was going "wrong" with the OP... so I aimed to disturb the underlying code as little as possible.

But with a litle more time on my hands, it being Saturday... see below.

Did you see my post where I mentioned that "the OS serialises read and write accesses to console devices."?

I did, thank you. And, as I said, when I tried a file attached to STDIN the "problem" went away. So, yes, the effect appears to be peculiar to the console.


  • the child thread doesn't attempt to read from or write to the console.

  • the main thread doesn't read from, but does write to the console, but doesn't appear to block there.

So... the serialization of console read and write access doesn't appear to be the issue.

Have you consider the effect of all your verbose logging, and tracing, and "determining the state of STDIN" is having upon the outcome you are seeking to establish?

I have.

Which is why the trace is gathered in memory and not output until the end. It does introduce a small critical region in the trace gatherer... but that should only affect the progress of the threads (which is arbitrary in any case) when they are runnable. So if my means of observing the problem has affected it, I'm blessed if I can see how.

I'm not sure what you mean by "determining the state of STDIN"... but if you mean the test to see if STDIN was open/closed after starting the "Terminal Watcher": then I can tell you that the main result is the same with or without that piece of code.

Reduced test case code:

use strict; use warnings; use threads; use Thread::Queue; use Time::HiRes qw(time) ; my $START = time() ; my @t = () ; push @t, [time(), "main thread start"] ; my $s_q = Thread::Queue->new ; async { $s_q->enqueue(time()) ; $_ = <STDIN> ; $s_q->enqueue(time()) ; }->detach() ; if (@ARGV) { # option to close STDIN close STDIN ; push @t, [time(), "closed STDIN"] ; } ; threads->yield() ; # make sure STDIN thread starts push @t, [time(), "about to start child thread"] ; my $c_q = Thread::Queue->new ; async { $c_q->enqueue(time()) ; }->detach() ; threads->yield() ; # make sure child thread starts push @t, [time(), "about to collect results"] ; push @t, [$s_q->dequeue(), "STDIN thread started"] ; push @t, [$s_q->dequeue(), "STDIN thread received input"] ; push @t, [$c_q->dequeue(), "child thread ran"] ; threads->yield() ; # give threads opportunity to complete push @t, [time(), "main thread completes"] ; foreach my $t (sort { $a->[0] <=> $b->[0] } @t) { printf "@ %9.6f: %s\n", $t->[0] - $START, $t->[1] ; } ;
which on my uni-processor, Windows XP, Perl 5.10.0, gives:
@  0.000006: main thread start
@  0.014843: STDIN thread started
@  0.015520: about to start child thread
@  9.814112: STDIN thread received input
@  9.824127: child thread ran
@  9.834141: about to collect results
@  9.834517: main thread completes
but if the main thread closes STDIN:
Z:\>perl close
@  0.000004: main thread start
@  0.008159: closed STDIN
@  0.008267: STDIN thread started
@  0.008845: about to start child thread
@  0.017748: child thread ran
@  0.022810: about to collect results
@ 10.725422: STDIN thread received input
@ 10.735437: main thread completes
(where the italics is me pecking at the keyboard to introduce a delay...)

FWIW, here's what my Linux box (also uni-processor, Perl 5.10.0) does:

[GMCH@hestia ~]$ perl
@  0.000012: main thread start
@  0.008300: STDIN thread started
@  0.008525: about to start child thread
@  0.024331: child thread ran
@  0.028648: about to collect results
@ 11.298085: STDIN thread received input
@ 11.298319: main thread completes
and closing STDIN makes no difference.

My hypothesis is: when creating the child thread the main thread is blocked because whatever "clones" STDIN cannot do so while some other thread is waiting on it -- where STDIN is attached to the console.

I can see how that could be related to the serialisation of access to the console device. Nevertheless, it is a bit of a surprise. Happily, closing STDIN does not block and does close the handle -- so there is a work around.

In reply to Re^6: threads on Windows by gone2015
in thread threads on Windows by kennethk

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?

What's my password?
Create A New User
Domain Nodelet?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (3)
As of 2024-04-12 14:09 GMT
Find Nodes?
    Voting Booth?

    No recent polls found