You can look at Thread :: Queue to do this work. You can configure a queue that will handle the signaling between threads waiting for a go signal and threads sending a go signal. Here is a quick layout that I have not tested:
... use Thread::Queue; ...
Threads that must wait for a go signal will wait for the dequeue method until something enters the queue. As soon as a message enters the queue, one thread and only one thread will capture the message and process it.
If you want to stop threads so that they do not start, you can insert a stop message in the head of the queue.
$q->insert(0, 'stop') foreach (@threads);
There are examples in Thread :: Queue and CPAN Distribution threads that show this in more detail.
In answer to your second question, the answer, unfortunately, depends. When you keep shutting down your threads, what kind of cleanup is required for a clean shutdown? What is the worst case scenario that can occur if a carpet breaks from a thread? You would like to plan at any time for the cleaning to take place. Another option you could do is to wait on each thread for it to actually complete.
The reason for my comment asking if it is possible to remove the detach
call is that this method allows the main thread to exit and does not care about what happens to any child threads. Instead, if you remove this call and add:
$_->join() foreach threads->list();
to the end of your main block, this will require the main application to wait for each thread to complete.
If you leave the detach
method in place, you will need to sleep at the end of your code if you need your threads to do any cleanup. When you call detach
on a thread, what you tell Perl is that you don't care what the thread does when your main thread terminates. If the main thread exits and there are threads that are still running that have been disconnected, the program will exit without warning. However, if you do not need to be cleaned up and you still call detach
, feel free to leave whenever you want.