Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

Re^4: Threads and signals in Windows

by bojinlund (Parson)
on Mar 10, 2013 at 07:01 UTC ( #1022651=note: print w/replies, xml ) Need Help??

in reply to Re^3: Threads and signals in Windows
in thread Threads and signals in Windows

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 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: +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?

Replies are listed 'Best First'.
Re^5: Threads and signals in Windows
by BrowserUk (Pope) on Mar 10, 2013 at 10:15 UTC
    Is it OK with “Sleep(0)”, or must it be a non zero parameter value?

    The problem here is the assumption that yielding the processor will ensure that the terminated thread has had time to fully clean up before this thread will get another timeslice and exit. If the system is busy, many other threads in the system are eligible to run -- especially if they are higher priority -- then the callee of TerminateThread() might easily get several timeslices before the thread actually ends.

    The correct (or maybe just better) thing to do, would be to pass a known exit code value on the TerminateThread() call and then loop checking the thread exit code until it returns that value rather than STILL_ACTIVE. Eg. Something like this:

    TerminateThread( hProcess, 123456789 ); Sleep( 0 ); GetExitCodeThread( hProcess, &exitCode ); while( exitCode != 123456789 ) { Sleep(0); GetExitCodeThread( hProcess, &exitCode ); }

    Once GetExitCodeThread() returns the known value, you should be pretty certain that the thread has actually terminated.

    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.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1022651]
and the radiator hisses contentedly...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (6)
As of 2017-05-29 15:56 GMT
Find Nodes?
    Voting Booth?