In theory and somewhat in practice Perl 6 neatly handles this for you with Supplies and taps handling signals in a thread safe sort of way. See "System events exposed as Supplies" in the Perl 6 design documents. The Perl 6 solution inspired me to write some Perl 5 code with similar capability that I have included below. Note that like the Perl 6 solution my code will "as is" do the actual handling of SIGINTs sequentially but it should be quite easy to add some parallel threads if wanted.
use strict;
use warnings;
use threads;
use Thread::Queue;
my $q = Thread::Queue->new(); # A new empty queue
my $thr = threads->create(
sub {
# Thread will loop until no more work
while (defined(my $item = $q->dequeue())) {
print "starting work on $item\n";
sleep 5;
print "finished work on $item\n";
}
}
);
my $item = 1;
{
local $SIG{INT} = sub { $q->enqueue($item++) };
kill 'INT', $$;
sleep 2;
kill 'INT', $$;
sleep 2;
}
$q->enqueue(undef); # I think in more modern Thread::Queue has $q->end
$thr->join();