worker thread does not yield to the main thread

Viewed 185

I have a minimal reproducible case where a worker thread is not yielding to the main thread, or IOW, the scheduler is not triggering a context switch to the main thread, or IOOW, the task in the worker thread is blocking the main thread.

I'm on Windows 10.0.18362 and using ActiveState Perl 5.28.

foo.pl:

use strict;
use File::Basename;
use threads; 
use Data::Dumper;

# sub yield {
#    sleep(1);
# }

sub wait_for_notepad {
   my @notepads = ();
   while (!scalar(@notepads)) {
      @notepads = grep /notepad\.exe/, qx(tasklist);
      print(Dumper(\@notepads));
      # yield();
   }
}

sub main {
   my $thr = threads->create(sub {
      # yield();
      system("cmd /c \"notepad.exe\"");
   });

   my $script_dir = dirname($0);
   my $output = qx(perl $script_dir\\bar.pl);
   print("$output");

   wait_for_notepad();
   system("taskkill /im notepad.exe /f /t");

   $thr->join();
}

main();

bar.pl (place in the same directory as foo.pl)

use strict;

print("hello from bar.pl\n");

Then run with perl path/to/foo.pl.

The docs mention a threads->yield(), but it also mentions that it's a no-op on most systems, which seems to be how it's behaving for me. Another option I found was to use a sleep() right before the worker thread calls system() (the commented parts of the code). Are there any other alternatives that would help me tell the worker thread to yield to the main thread?

Edit:

Sorry for being unclear. The exact sequence of behavior I'm seeing from this is when the script is ran, notepad opens up. I'm expecting to see bar.pl print "hello from bar.pl" in the console concurrently, but that does not happen. The main thread sits there blocked for several seconds with nothing printed to stdout until I interactively close notepad. Is this expected behavior? Perhaps there's a better way to achieve parallel/multi processing in perl, or I'm just doing this wrong.

Edit:

Also, if I edit the line where I have my $output = qx(perl $script_dir\\bar.pl); to system("perl $script_dir\\bar.pl"), the problem disappears and no blocking occurs.

Edit:

Title may be misleading. Sorry about that. I'm bad at making titles when it's late in the day =P. By "yield", I mean some worker thread gets interrupted to give some time to the main thread. But that's weird too b.c. if each thread is running on their own core then you'd get parallel processing anyway, so "yielding" makes no sense in this context. Anyway, never mind all that; in any case, the title should've been something more like "process deadlock when using perl threads api with no synchronization primitives". That's probably more accurate here.

0 Answers
Related