In the use of ACL Library development high concurrency semi-resident thread pool program describes how to use the C version of ACL line libraries to write multithreaded programs, this article will show how to use the C + + version of ACL line libraries to write multithreaded programs, although the C + + version of the ACL line libraries based on the C version of the line libraries, but provides a more Definition of a clear and concise interface (many places refer to the JAVA thread interface definition). The following is a simple example of using threading:
#include "ACL_CPP/LIB_ACL.HPP"/////////////////////////////////////////////////////////////////////////// / Sub-threading class definition Class mythread : public acl::thread{public:mythread () {}~mythread () {}protected:// base class pure virtual function, which is called when the start function of a thread instance is called in the main thread// the virtual function is invoked Virtual void* run () {const char* myname = "Run";p rintf ("%s: thread id: %lu, %lu\r\n", MYNAME, THREAD_ID (), acl::thread::thread_self ()); return null;}};/ Static void test_thread ( void) {const char* myname = "test_thread";mythread thr; // Child Thread object instance// Set the properties of the thread to be non-detached so that the following can be called wait// wait for the thread to end thr.set_detachable (false);// start a child thread if ( Thr.start () == false) {printf ("start thread failed\r\n"); return;} printf ("%s: thread id is %lu, main thread id: %lu\r\n ", myname, thr.thread_id (), acl::thread::thread_self ());// wait for the child thread to run end if (thr.wait ( NULL) == false) printf ("wait thread failed\r\n"); elseprintf ("wait thread ok\r\n") ;} Int main (void) {// initialization acl Library acl::acl_cpp_init (); Test_thread (); #ifdef win32printf (" Enter any key to exit ...\r\n "); GetChar (); #endifreturn 0;}
From the above example, it is very simple to create a thread libraries using ACLs. Opening the lib_acl_cpp/include/acl_cpp/stdlib/thread.hpp file, you can see the declaration of the thread class, which has two base classes: Acl::thread and Acl::thread_job, in the base class ACL:: Thread_job has a pure virtual function run (), Acl::thread also inherits from Acl::thread_job, the user's threading class needs to inherit Acl::thread, and it needs to implement the pure virtual function of the base class Acl::thread_job: Run (). When the application invokes the start () function of a thread instance in the main thread, the ACL line libraries creates a child thread inside, and the child thread is created and the thread object's run () function is called. Here are a few of the main method definitions in the Acl::thread class:
Class thread_job{public:thread_job () {}virtual ~thread_job () {}/** * pure virtual function, Subclasses must implement this function, which executes in a child thread * @return {void*} parameters returned before the thread exits */virtual void* run () = 0;}; Class thread : public thread_job{public:thread (); Virtual ~thread ();/** * Starts the thread procedure, and once the function is called, it starts a new * child thread, executes the base class thread_job::run procedure in the child thread * @return { bool} if the thread */bool start ();/** * was created successfully, this function can be called when the thread is created as a non- detachable state * Wait for thread to end, otherwise, if the thread is created as detachable status * will error when calling this function * @param out {void **} When this parameter is not a null pointer, this parameter is used to hold the parameters returned before the * thread exits * @return {bool} succeeded */bool wait (void** out = null);/** * Call this function before calling start to set whether the created thread is * Detach (detachable) status, if this function is not called, the line Cheng created * is considered detached state * @param yes {bool Whether the} is dividedAway from status * @return {thread&} */thread& set_detachable (bool yes);/** * Call this function before calling start to set the stack size of the thread being created * @param size {size_t} thread stack size when the value is 0 or do not * call this function, the thread stack size created is the default value of the system * @return {thread&} */ Thread& set_stacksize (size_t size);/** * call this function after calling start to get the id of the created thread No. * @return {unsigned long} */unsigned long thread_id () const;/* * * thread id number * @return {unsigned long} */static for the current caller Unsigned long thread_self (); ....};
From the thread example above and the class definition of Acl::thread, one might think that Acl::thread_job's pure virtual method: Run () is placed in the Acl::thread class, and even the Acl::thread_job class is redundant, but because the ACL library Also supports thread pool mode, then acl::thread_job is necessary. In the LIB_ACL_CPP\INCLUDE\ACL_CPP\STDLIB\THREAD_POOL.HPP header file, you can see the declaration of the ACL's thread pool class Acl::thread_pool, the main function interface for the class is as follows:
class thread_pool{/** * start the thread pool, after you create the thread pool object, you must first call this function to start the thread pool */void start ();/** * Stop and destroy the thread pool and release the thread pool resource, call this function to make all child threads exit, * But do not release this instance, if the class instance is dynamically allocated then the user should self-dispose of the class instance, * after calling this function, If you want to restart the thread pool procedure, you must call start procedure */void stop ();/** * all the thread pools in the thread pool to finish all the tasks */void wait ();/** * a task to one thread in the thread pool to execute, and the * thread in the thread pool executes the run function in that task * @ param job {thread_job*} thread Task * @return {bool} succeeded */bool run ( Thread_job* job);/** * a task to a thread in a thread pool to execute, the thread pool of * threads will perform the task of the run function, the function and The run function is exactly the same, just to provide this interface for * to make JAVA programmers look more familiar * @param job { thread_job*} thread Task * @return {bool} succeeded */bool execute (thread_job* job ;/** * call this function before calling start to set the stack size of the thread being created * @param size {size_t} The thread stack size, when the value is 0 or not &Nbsp;* Call this function, the thread stack size created is the default value of the system * @return {thread&} */thread_pool& Set_stacksize (size_t size);/** * set thread pool maximum number of threads limit * @param max {size_t} Maximum number of threads, if this function is not called, the internal default value is 100 * @return {thread_pool&} */thread_pool& set_ Limit (Size_t max);/** * set timeout for idle threads in thread pool exit time * @param ttl {int} idle timeout (seconds) , if you do not call this function, the internal default is 0 * @return {thread_pool&} */thread_pool& set_idle (int  TTL); ......};
These interface definitions are also relatively straightforward, given an example of using a thread pool:
Thread work Class Class myjob : public acl::thread_job{public:myjob () {}myjob () {} The pure virtual function in the protected:// base class Virtual void* run () {const char* myname = "Run";p rintf ( "%s: thread id: %lu\r\n", Myname, acl::thread::thread_self ()); return null;}};/ Thread Pool class Class mythread_pool : public acl::thread_pool{public:mythread_pool () {}~mythread_pool () {printf ("thread Pool destroy now, tid: %lu\r\n ", acl::thread::thread_self ());} protected:// the virtual function of the base class, which is called when the child thread is created Virtual bool thread_on_init () {Const char* myname = "Thread_on_init";p rintf ("%s: curr tid: %lu\r\n", myname,acl::thread::thread_ Self ()); return true;} base class virtual function, the virtual function will be called virtual void thread_on_exit () before the child thread exits () {const char* myname = "Thread_on_exit";p rintf ("%s:&Nbsp;curr tid: %lu\r\n ", myname,acl::thread::thread_self ());}};/ Void test () {acl::thread_pool* threads = new mythread_pool (); Threads->start (); // start thread pool procedure Acl::thread_ Job *job1= new mythread, *job2 = new mythread;threads->execute (JOB1); Threads->execute (JOB2);// to ensure that job1, job2 dynamic memory is properly freed,// must call threads->stop Waits for the child thread to run at the end of the// main thread to release threads->stop ();d elete threads;// release dynamically allocated objects in the main thread delete job1; DELETE JOB2;}
As shown in the example above, when using the C + + version thread pool class library of ACLs, you must define a thread work class (inherited from Acl::thread_job) and implement a pure virtual function of the base class: Run (); In addition, when using the thread pool, If you want to initialize some thread local variables while threads are being created and release some thread local variables before threads exit, you can define Acl::thread_pool subclasses, implement the Thread_on_init and Thread_on_exit methods in the base class, and if not, You can use the Acl::thread_pool class object directly.
Download: http://sourceforge.net/projects/acl/
SVN:SVN Checkout Svn://svn.code.sf.net/p/acl/code/trunk Acl-code
Github:https://github.com/zhengshuxin/acl
QQ Group: 242722074
Writing multithreaded applications using ACL libraries