Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Re: Threads and signals in Windows

by BrowserUk (Patriarch)
on Mar 08, 2013 at 10:37 UTC ( [id://1022385]=note: print w/replies, xml ) Need Help??


in reply to Threads and signals in Windows

Using signal in an inappropriate way can result in a stochastic behaviour of Perl programs. I have seen cases when this not just influence the Perl program, but also other processes in the Windows system. In some cases it is even not possible to switch off the system in the normal way.

Sorry n'all, but that is garbage! Whilst you may have seen some symptoms like these and have attributed them to the use of signals; I'll bet that you cannot post code to demonstrate it.

As for the rest: Unix Signals are (one of several) "Unfixable designs". And most all the caveats and warnings you quoted from the MS docs for TerminateThread() are equally applicable to causing any piece of code to be interrupted without resumption using a longjump. Ie. Signals.

As an IPC mechanism, that only conveys 1 bit of information and is edge triggered -- ie. missable unless you happen to be ready for them -- signals are a piss poor substitute for proper IPC mechanisms.

And the need to use them to abandon in-progress processing is a sign of badly designed code. Describe the use case for using them and I'll outline a better way of tackling the problem. (Though it may or may not be currently available from Perl.)


With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re^2: Threads and signals in Windows
by bojinlund (Monsignor) on Mar 09, 2013 at 08:54 UTC

    BrowserUk, thank you! I appreciate your straightforward answers.

    Sorry n'all, but that is garbage! Whilst you may have seen some symptoms like these and have attributed them to the use of signals; I'll bet that you cannot post code to demonstrate it.
    This is a case of, as I believe, an inappropriate usage of signals, and the related symptoms of system degeneration. It is from https://rt.cpan.org/Public/Bug/Display.html?id=66437
    I am using:
    • Strawberry-perl-5.12.2.0
    • Perl 5, version 12, subversion 2 (v5.12.2) built for MSWin32-x86-multi-thread
    • Windows 7 Home Premium with Service Pack 1

    I have used version 1.11 and 1.12 of Test::TCP.

    Problem: The test in Test::TCP is blocking. Get the system in state, that it must be restarted. It is sometimes not possible to kill the blocked processes. I even get errors like “Can't spawn "cmd.exe"” when using the system call. It indicates a degeneration of the perl interpreter.

    One example of stochastic behavior (from https://rt.cpan.org/Public/Bug/Display.html?id=66016) is running this batch file:
    @echo off set count=0 :loop set /a count=%count%+1 echo Count %count% @echo on perl -e "if ($pid=fork){Win32::Sleep(0); kill(9, $pid); Win32::Sleep(0 +)}else {sleep 1000}” if errorlevel 1 goto exit @echo off goto loop :exit ECHO.%ERRORLEVEL%

    Examples of results I got was:

    • Blocking after 38 to 2806 loops.
    • Running more than 7000 loops.
    • Exiting with the value 9 after 1-7 loops.

    This was done using Strawberry-perl-5.12.2.0. The patch http://perl5.git.perl.org/perl.git/commitdiff/82e24582 removed most of the problem but not all. It was also found that version of the Windows operating system had different behavior.

    As for the rest: Unix Signals are (one of several) "Unfixable designs". And most all the caveats and warnings you quoted from the MS docs for TerminateThread() are equally applicable to causing any piece of code to be interrupted without resumption using a longjump. Ie. Signals.

    As an IPC mechanism, that only conveys 1 bit of information and is edge triggered -- ie. missable unless you happen to be ready for them -- signals are a piss poor substitute for proper IPC mechanisms.

    And the need to use them to abandon in-progress processing is a sign of badly designed code. Describe the use case for using them and I'll outline a better way of tackling the problem. (Though it may or may not be currently available from Perl.)

    I interpret your standpoint as:

    • Many implementations of signals are "unfixable". Not just the one in the implementation of Perl in Windows.
    • Signals are no proper IPC mechanisms.

    Could you accept (or even recommend) the addition of something like this:

    It is strongly advice against using signals for Inter Process Communication. This is particular important in Perl code intended to be portable.

    to the Perl documentation? The addition could be done to the function kill in the Perl Language reference.

      One example of stochastic behavior...

      You reinvented a fork bomb. Except on windows, fork actually spawns a thread; so it might better be termed a thread-bomb in this case.

      Try feeding this:  :(){ :|:& };: to bash on a *nix system and see how deterministic the DoS is.

      You are also asking the child 'process' to kill its parent 'process'; but on windows they are actually just threads within the same process. Ie. You are attempting to kill your own process. In addition, you are also thread-bombing the system from within that same process. Is there any wonder that the process may not respond to the request in a predictable manner?

      And you are using a random delay -- sleep 0 equates to "relinquish the rest of the current timeslice" which is an unknowable quantum of time, that could range from 0 microseconds -- if the timeslice was about to end anyway; or if there are no other processes in the system immediately eligible to run -- to N * q where N is the number of other processes and threads in the system that are eligible to run; and q is the scheduler quantum which can vary from ~5 to ~180 microseconds depending upon: a) the version of Windows; b) how that version is configured (workstation or server; foreground or background priority); c) a whole bunch of other factors.

      In other words; you have programmed a random delay into your program as surely as if you had written Win32::Sleep( rand()*100 ).

      Of course the behaviour is "stochastic"; That's how you programmed it to be!

      Could you accept (or even recommend) the addition of something like this:

      Neither!

      I use kill (on windows) to good effect all the time. The difference is that I have spent enough time to understand the limitations of the emulation on my platform. I understand that they give me a fairly crude interface to the native Console control handler functionality from Perl; and that -- used carefully -- can provide functionality that I might otherwise have to dip into Inline::C or XS to gain access to.

      What I would say; and have said many times; is do not attempt to use fork & the windows signals emulation to try to port *nix idioms to windows; because you will be sadly let down.

      The basic problem here is the entire attempt to make Windows look like or work like some variant of *nix. It is simply far easier to write two scripts -- one for each platform -- than to try and construct and maintain one that will operate correctly on both platforms.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

        BrowserUk, thank you!

        What I would say; and have said many times; is do not attempt to use fork & the windows signals emulation to try to port *nix idioms to windows; because you will be sadly let down.

        Based on this, I will propose an addition to the documentation of function fork (and perhaps also kill) in the Perl Language reference.

        You reinvented ... a thread-bomb.

        And you are using a random delay -- sleep 0 equates to "relinquish the rest of the current timeslice" which is an unknowable quantum of time, that could range from 0 microseconds

        My “thread-bomb” resulted in a patch. The patch http://perl5.git.perl.org/perl.git/commitdiff/82e24582 adds to t/op/fork.t:

        +system $^X, "-e", "if (\$pid=fork){sleep 1;kill(9, \$pid)} else {sle +ep 5}";

        Is this also a thread-bomb, or is it OK with non zero sleep?

        The patch also changes win32/win32.c:

        --- a/win32/win32.c +++ b/win32/win32.c @@ -1282,6 +1282,13 @@ win32_kill(int pid, int sig) case 9: /* kill -9 style un-graceful exit */ if (TerminateThread(hProcess, sig)) { + /* Allow the scheduler to finish cleaning up the +other thread. + * Otherwise, if we ExitProcess() before another +context switch + * happens we will end up with a process exit cod +e of "sig" instead + * of our own exit status. + * See also: https://rt.cpan.org/Ticket/Display.h +tml?id=66016#txn-908976 + */ + Sleep(0); remove_dead_pseudo_process(child); return 0; }

        Is it OK with “Sleep(0)”, or must it be a non zero parameter value? Can the non zero time value cause that we still sometimes get 9 as an erroneous exit value? What is the smallest non-zero value that can be used?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1022385]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (4)
As of 2024-04-19 21:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found