C implements a thread pool follow-up that pursues

Source: Internet
Author: User
Tags epoll semaphore

Introduction -_- or the old routine start

A long time ago wrote a quest thread pool, C implementation of the pursuit of thread pool exploration

It's a way of thinking, and it's realized. can be used. Recently in detail to engage in Simplec framework. Ready to release a full version.

Just in passing to optimize the thread pool. The results of the optimization are as follows.

1). More beautiful and reasonable API

2). pthread Threading API Optimization

3). On the basis of solving surprise group, further, precision positioning.

4). Added more security code

A little bit, thread pool is not a lot of application scenarios for historical language C, C + +. can be resolved with a thread, can be resolved with Message Queuing.

Of course, the thread has a different property is the preemption. When you're looking for performance, that's basically not enough.

At least there is no need for preemptive tasks in modern game frame design.

The following allow me to elaborate ideas, scthreads.h

#ifndef _h_simplec_scthreads#define_h_simplec_scthreads#include<schead.h>////This is a library of thread pools. Support asynchronous cancellation also adds some thread help libraries//typedefstructThreads *threads_t;////Thread_run-Opens a self-destruct thread running run//Run : The running body//parameters of the Arg:run//return: >= success_base indicates success//extern intThread_run (Die_f Run,void*Arg);////threads_create-Create a thread pool to process objects//Return : Returns the created thread pool object, NULL indicates failure//externthreads_t Threads_create (void);////Threads_delete-asynchronously destroys a thread pool object//Pool: Thread Pool Object//return:void//extern voidThreads_delete (threads_t pool);////Threads_add-adding tasks to process in the thread pool//Pool: Thread Pool Object//run: Running the execution of the problem//parameters of the Arg:run//return:void//extern voidThreads_add (threads_t pool, Die_f run,void*Arg);#endif //!_h_simplec_scthreads

Can be explained by the above 1). A more aesthetically sound API because macros are used internally to determine the optimal number of threads. No need for the player to specify. Of course, this value is small.

Preface-_-to order an appetizer.

Sometimes when we use pthread threads, the steps are a little cumbersome. We don't really need to know what this thread is doing after the thread has finished executing.

Just want to simply help me to execute a method asynchronously. The Thread_run function is designed here.

void    (* die_f) (void * node); extern int void * arg);

Detailed design routines. As follows

#include <pthread.h>//the running BodystructFunc {die_f run; void*arg;};//entities executed by Pthread in Thread_runStatic void* _run (void*Arg) {    structFunc * func =Arg; Func->run (func->Arg);  Free(ARG); returnNULL;}////Async-Opens a self-destruct thread running run//Run : The running body//parameters of the Arg:run//return: >= success_base indicates success//intAsync (Die_f run,void*Arg)    {pthread_t tid;    pthread_attr_t attr; structFunc * func =malloc(sizeof(structfunc)); if(NULL = =func) RETURN (Error_alloc,"malloc sizeof (struct func) is error"); Func->run =run; Func->arg =Arg; //build pthread thread run upPthread_attr_init (&attr); Pthread_attr_setdetachstate (&attr, pthread_create_detached); if(Pthread_create (&tid, &attr, _run, func) <0) {         Free(func); Pthread_attr_destroy (&attr); RETURN (Error_base,"pthread_create error Run, arg =%p |%p.", run, ARG); } Pthread_attr_destroy (&attr); returnsuccess_base;}

Here's a little bit, the first one is the generic error enumeration that I commonly use.

////flag_e-Global Operation basic behavior returns an enumeration that is used to determine the status code of the return value status//>= 0 Identifies success status, < 0 identifies error status//typedefenum{success_exist= +2,//want to exist, the settings already exist before.Success_close = +1,//The file descriptor read is closed and the read is completed to return thisSuccess_base = +0,//The result is a correct return macroError_base= -1,//Error base type, all errors are available to it, in the case of unclearError_param =-2,//wrong parameter for callError_alloc =-3,//Memory allocation ErrorERROR_FD =-4,//File open failedError_tout =-5,//Timeout Error} flag_e;

The project is well used in actual combat. The basic one function returns the error on those.

and the 2nd. When we use Pthread_attr_init, POSIX threads recommend that we immediately also have to call Pthread_attr_destroy.

Make sure your own things are free. In fact Pthread_*_destroy such functions simply return the current thread state and do not involve resource destruction content.

Then the 3rd, good return macro, or quite floating.

// //The console outputs a complete message prompt, where FMT must be a "" wrapped string//Cerr-Easy message Printing//output error message Cerr_exit, and roll out the current process//cerr_if-If statement check to exit if standard error is met// #ifndef _h_cerr#define_h_cerr#defineCerr (FMT, ...) \fprintf (stderr,"[%s:%s:%d][errno%d:%s]"Fmt"\ n", __file__, __func__, __line__, errno, Strerror (errno), # #__VA_ARGS__)#defineCerr_exit (fmt,...) \Cerr (FMT, # #__VA_ARGS__), exit (Exit_failure)#defineCERR_IF (Code)if(Code) <0) Cerr_exit (#code)////Return -Print the error message and return the specified result//Val:return, when the need to return void, time to fill ', ' or NIL//FMT: Formatted string wrapped in double quotes//...: the corresponding parameter in the FMT//Return:val// #defineNIL#defineRETURN (Val, FMT, ...) Do{Cerr (FMT, # #__VA_ARGS__); returnVal; }  while(0)#endif

# # is to solve the problem with only one parameter in the mutable parameter (...). No content for empty, gcc compiler however).

NIL is to resolve return void; syntax is replaced by the syntax sugar of RETURN (NIL).

Back to the point, the above function actually embodies 2). Pthread Threading API Optimizations . Mainly reflected in my use

    Pthread_attr_init (&attr);    Pthread_attr_setdetachstate (&attr, pthread_create_detached); 

To replace
Pthread_detach (Pthread_self ());

Move the thread to start the running settings, moving to the outside of the thread initialization. It means to be owned by creation.

Reduce the coupling of the thread control code, the trace for the thread business code speed up.

Start slow and run fast. Or do not know when it is difficult to know, familiar with good to get along in fact better. O (∩_∩) o haha ~

Detailed design of body-_-

First look at the core structure, each thread object

// thread structure body, one semaphore per thread, fixed-point trigger struct Thread {    struct thread * NEXT;        // Next Thread Object    bool wait;                   // True indicates that the current thread is suspended    pthread_t Tid;               // Current thread ID    pthread_cond_t cond;         // thread condition variable };

The thread startup object is a linked list. Wait indicates that the current thread is pending and is used to quickly activate a suspended thread.

Static pthread_cond_t * _threads_getcont (struct threads * pool) {        struct thread * head = pool->thrs;      while (head) {        if (head->wait)            return &head->cond;        = head->next;    }     return NULL;}

where struct threads is the scheduling structure for all thread objects.

//Define a thread pool (threading set) definitionstructthreads {size_t size; //Thread pool size, maximum number of threaded fabric bodiessize_t Curr;//the total number of threads in the current thread poolsize_t Idle;//number of idle threads in the current thread poolpthread_mutex_t Mutx;//Thread Mutex Amount    structThread * thrs;//thread structure Body object Set    structJob * HEAD;//the chain header of the thread task list, the queue structure    structJob * TAIL;//Thread Task Queue footer, post-insert execution};

The task job employs a queue structure. Line threads consumes this producer queue at the same time.

The above wait design embodies 3). On the basis of solving the surprise group, further, precision positioning.

For 4th 4). Added more security Code Our approach is reflected in the property control of the Pthread thread.

    // Set thread properties, set thread to allow exit thread     pthread_setcancelstate (pthread_cancel_enable, NULL);    Pthread_setcanceltype (pthread_cancel_asynchronous, NULL);

Sets the on thread cancellation state and supports asynchronous cancellation.

    // build threads, build complete directly    if 0 ) {        * cond = _threads_getcont (pool);         // Release the lock and send the signal to activate the thread, the speed is fast, the disadvantage loses the thread execution priority         Pthread_mutex_unlock (MUTX);         // Sent to the idle thread, this semaphore must exist         pthread_cond_signal (cond);         return ;    }

The point sends the signal, the precision solves the surprise group phenomenon. be able to change time with space, but don't waste it.

Pull a bit of other surprises, such as epoll in multiple processes. After Fork Epoll, accept only one success, multiple failures.

Solutions are also available. The simplest is to ignore the surprise group error, but performance is somewhat affected. You can also poll file descriptor processing by equalization.

For a detailed description of this thread pool, you can look at the following source files and test files

  Scthreads.h

  Scthreads.c

Test_scthreads.c

Finally, the main reason for the change is that the previous version was too ugly to be. Feel beauty is good, beauty is a pleasant feeling ~ _φ (°-°)/

What to do for the beauty, then the whole chant ~

PostScript-_-save a bit more memory, maybe forget

The problem is inevitable, only the grinding of the ~

The story of the North http://music.163.com/#/song?id=37782112

  

  You envy my heart no distractions , I envy your happy life

  

C implements a thread pool follow-up that pursues

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.