Thread(3pm)

πŸ“¦
version 0.015 Β· 2 versions
, in debian bookworm, debian trixie, ubuntu jammy, ubuntu noble

πŸ’– Thread(3pm) πŸ’–

okay bestie, gather round, because this is the manual page for Thread(3pm) and it is literally the whole vibe for POE::Component::Pool::Thread β€” a POE-managed boss/worker threadpool. no cap. let's get into it πŸ’…


🌸 NAME 🌸

POE::Component::Pool::Thread β€” A POE Managed Boss/Worker threadpool. that's it, that's the name, iconic πŸŽ€


✨ SYNOPSIS ✨

here's the whole look, fr fr:

use POE qw( Component::Pool::Thread );

POE::Component::Pool::Thread->new
   ( MinFree       => 2,
     MaxFree       => 5,
     MaxThreads    => 15,
     StartThrneads => 5,
     Name          => "ThreadPool",
     EntryPoint    => \&thread_entry_point,
     CallBack      => \&result_handler,
     inline_states => {
         _start => sub {
              my ($kernel, $heap) = @_[ KERNEL, HEAP ];

              # We are inside the component session
              $kernel->yield(run => @arguments);

              $kernel->post(ThreadPool => run => @arguments);
         },
     }
   );

sub thread_entry_point {
   my (@arguments) = @_;

   return 1;
}

sub result_handler {
   my ($kernel, $result) = @_[ KERNEL, ARG0 ];

   $result == 1;
}

(yes, StartThrneads is spelled like that in the original and we are NOT fixing it, we do not touch the sacred text πŸ™ˆ)


πŸ¦‹ DESCRIPTION πŸ¦‹

so basically? this is an expand-on-demand thread pool, and it's managed through a POE session in a way that does not interfere with cooperative multitasking. one single pipe gets created, and every thread tells the main process what's up through that pipe. no serialization happening here (these are threads, not child processes, hello), so the execution is very fast. slay πŸ’–


πŸ‘‘ RATIONALE πŸ‘‘

the tea is: cooperative co-routine style programming isn't always on the menu. some third-party software (dependent libraries and/or modules, you know the ones) and certain tasks will block processing whether you like it or not. 😭

also, creating threads is a LOT of overhead β€” in fact, quite a bit more overhead under the current implementation of ithreads than fork is. so obviously the move is to allocate those resources before you need them. if you create the threads and re-use them, they're just... around when you need them, no horrendously slow threads->create() call required. main character resource management, periodt ✨

and here's the thing about getting results back: communicating the results of a thread's processing requires letting it exit. which means you'd be stuck eating the threads->create() overhead again next time you need to do the same task. πŸ’€ with a thread pool designed in this fashion, though, the main thread itself has its own process loop. the result of each iteration gets passed through a thread-safe queue, so you can collect the results of a thread's execution without the thread exiting. chef's kiss, honestly 🫢


πŸŽ€ CONSTRUCTOR πŸŽ€

new MANY THINGS

new is the only package method this package gives you. it builds a POE thread pool session, and you describe that session with these arguments:

  • EntryPoint CODE β€” this describes the entry point of the thread, and it's required. except, plot twist: in the actual implementation it's not actually an entry point. it's a coderef the thread will call repeatedly. πŸ” the arguments this subroutine gets are the arguments received by the controlling session. now listen carefully bestie: if you wanna pass references as arguments, every reference must be shared (threads::shared). filehandles and blessed references cannot be shared β€” you'll have to translate those yourself. for filehandles, just pass the file descriptor and reopen it in the child thread. for blessed references, pass the data structure only, and rebless the reference inside the thread. iykyk πŸ’…
  • CallBack CODE β€” this one describes the result handler, which is where the captured results of a thread's last execution get sent. same deal as the EntryPoint subroutine arguments: any data structures you want to pass through in return results must be explicitly shared (threads::shared). no shortcuts πŸ“
  • Name ALIAS β€” this describes the default alias your threadpool session gets handed. cute little name tag 🏷️
  • StartThreads INTEGER β€” this describes how many threads the component creates during its "_start" state, aka when the POE Session is being started. this should be a number greater than MinFree and less than or equal to MaxFree. rules are rules 🌈
  • MaxThreads INTEGER β€” this describes the maximum number of threads this component will create for this task. if the component gets assigned more tasks than threads, it drops the leftovers into an internal FIFO queue and hands them threads as those threads finish their tasks. a whole queue just sitting there, patient, iconic ✨
  • MinFree INTEGER β€” this sets the minimum number of free threads to maintain. when the component gets a new task, if there are fewer than this many threads available, it yields a request to create a new thread at the component's convenience. so polite about it πŸ’œ
  • MaxFree INTEGER β€” this provides the maximum number of free threads to maintain. upon completion of a task, this value gets checked. if there are more free threads available than this value, the oldest thread is asked to shut down. sorry grandma thread, your time has come 😭

🌟 INLINE STATES 🌟

  • run LIST β€” the run state assigns a task to one of the free threads in the pool, or appends the task to the component's internal FIFO if no threads are available and our thread resources are exhausted. either way, it's getting handled 🫑
  • shutdown β€” this state politely asks all threads to exit, deletes the wheel watching the one-way pipe the threads are using to communicate, removes the session alias, and awaits a clean session shutdown. so well-mannered, we love a graceful exit πŸŽ€

πŸ’€ BUGS πŸ’€

oh, i'm pretty sure of it. if you find some, let me know. πŸ™ˆ


πŸ’œ THANKS πŸ’œ

  • Matt Cashner
  • Rocco Caputo

absolute legends, we appreciate you 🫢


⭐ AUTHOR ⭐

Scott McCoy (tag@cpan.org)


and that's the whole page bestie!! perl v5.26.2, dated 2018-08-22, straight from the Thread(3pm) files πŸ’–βœ¨ go forth and thread responsibly, ily πŸ¦‹πŸŒΈ