Multithreading – how to control multithreading synchronization in Perl

I have an array of [A-Z, A-Z] ASCII numbers, as follows: my @ alphabet = (65.. 90,97.. 122);

So the main thread function is to check each character from the alphabet and return a string if the condition is true

Simple example:

my @output = ();
    for my $ascii(@alphabet){
      thread->new(\sub{ return chr($ascii); });
    }

I want to run threads on each ASCII number, and then put the letters in the thread function into the array in the correct order

Therefore, the out case array @ output should be dynamic and contain [a.. Z, A-Z] after all threads finish their work

How do I check if all threads have been completed and keep the order?

Solution

You are looking for $thread - > join, which waits for a thread to complete It may also be helpful to record here, this so question

Because in your case, it seems that the work done in the thread is roughly the same in cost (no thread takes longer than any other thread), you can join each thread in order, just like this, and wait for them to complete:

# Store all the threads for each letter in an array.
my @threads = map { thread->new(\sub{ return chr($_); }) } @alphabet;
my @results = map { $_->join } @threads;

Because when the first thread returns from the join, other threads may have completed and just wait for "join" to get their return code, or they are about to complete, which will make you very close to the parallelism of "as soon as possible". Moreover, since threads are created in order, @ results has been ordered for free

Now, if your threads may take different times to complete, or you need to perform some time-consuming processing in the main / build thread before inserting the "child thread" results into the output data structure, it may not be good to connect them sequentially In this case, you need to: a) detect the thread "exit" event, or b) poll to see which threads have exited

You can detect thread "exit" events using signals / notifications sent from child threads to main / build threads The simplest / most common method is to use cond in threads:: shared_ Wait and cond_ Signal function The main thread will wait for signals from child threads, process their output, and store it in the result array If you use this method, you should pre allocate the result array to the correct size and provide the output index for your thread (for example, use C-style for loops when creating threads and let them return ($result, $index_to_store) or similar), so you can store the results in the correct location, even if they are not faulty

You can use is_ The joinable thread instance method polls which threads are completed, or uses the threads - > list (threads:: joinable) and threads - > list (threads:: running) methods (hopefully not busy) in the loop to wait for one; Adding a sleep call – even a sub second call starting from time:: hires – will save a lot of performance / battery in this case) to detect when things are done and get results

Important: generating a large number of threads to perform a large amount of work in parallel, especially if the workload is small / fast, may lead to performance problems, And it may be better to use a small number of threads instead of a "work" (for example, a small number of threads are generated, and each thread uses the thread:: shared function to lock and pop up the first item in the shared array of "work to do", rather than mapping to process threads in a 1:1 manner. 1:1 mapping produces two main performance problems:

>The cost of generating and adding each thread (memory and time) is much higher than you think (benchmark, it does nothing on the thread, just returns and looks) If you need to do fast work, the thread management overhead of a large number of threads will be much slower than that of only managing some reusable threads. > If you end up with far more threads than the logical CPU core, and each thread is doing CPU intensive work, or each thread is accessing the same resources (for example, reading from the same disk or the same row in the database), you will soon encounter a performance cliff Adjusting the number of threads to the following "resources" (whether CPU or hard drive or the like) tends to produce better throughput than the thread scheduler switching between more threads rather than the available resources to run them There are many reasons why this is slow: > because the thread scheduler (part of the operating system, not the language) cannot fully understand what each thread is trying to do, preemptive scheduling cannot optimize performance at a certain point because of limited knowledge. > The operating system usually tries to give most threads a reasonable and fair shot, so it can't reliably say "let one run complete and then run the next" unless you explicitly add it to the code (because the alternative will starve unpredictably) and some threads will run) Basically, switch between "run a thread 1 on resource X" and "run a thread 2 on resource X". Once there are more threads than threads, you won't get anything and increase some overhead

TL; Dr threads do not improve performance for a certain period of time, after which they degrade performance If possible, reuse multiple threads corresponding to available resources; Do not create / destroy a single thread corresponding to the task to be completed

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>