search
HomeSystem TutorialLINUXThe use of thread pool under Linux C

The use of thread pool under Linux C

Feb 13, 2024 am 11:33 AM
linuxlinux tutoriallinux systemlinux commandshell scriptembeddedlinuxGetting started with linuxlinux learning

Do you often encounter the problem that the server load is too high and cannot be accessed normally? Then, you need to understand a very important concept in Linux systems-thread pool. By properly configuring the thread pool, you can effectively avoid server overload and improve system stability and reliability.

Thread pool is also a multi-thread processing method. The "producer" thread proposes tasks and adds them to the "task queue", and then some threads automatically complete the tasks on the "task queue".

Linux C下线程池的使用

Multi-threaded programming, create a thread, specify it to complete a certain task, and wait for the thread to exit. Although it can meet programming needs, when we need to create a large number of threads, a large amount of CPU may be consumed during the creation and destruction of threads, adding a lot of overhead. For example: copy of folder, response from WEB server.

The thread pool is used to solve a problem like this, which can reduce the overhead caused by frequent creation and destruction of threads.

Thread pool technology idea: Generally, pre-created thread technology is used, that is, a certain number of required threads are created in advance. After these threads are created in advance, assuming there are no tasks in the "task queue", then let these threads sleep. Once there is a task, wake up the thread to execute the task. After the task is executed, there is no need to destroy the thread until you want to When exiting or shutting down, at this time, you call the function that destroys the thread pool to destroy the thread.

The thread will not be destroyed after completing the task, but will automatically execute the next task. Moreover, when there are many tasks, you can have a functional interface to increase the number of threads. When there are few tasks, you can have a functional interface to destroy some threads.

If the time to create and destroy threads is negligible compared to the time to execute tasks, then we do not need to use a thread pool in this case.

"Task Queue" is a shared resource with "mutually exclusive access"

Linux C下线程池的使用

The thread pool is essentially a data structure and requires a structure to describe it:

struct pthread_pool //线程池的实现 
{ 
 //一般会有如下成员 
 
 //互斥锁,用来保护这个“任务队列” 
 pthread_mutex_t lock; //互斥锁  
  
 //线程条件变量 表示“任务队列”是否有任务 
 pthread_cond_t cond; //条件变量 
  
 bool shutdown; //表示是否退出程序 bool:类型 false / true 
 
 //任务队列(链表),指向第一个需要指向的任务 
 //所有的线程都从任务链表中获取任务 "共享资源" 
 struct task * task_list; 
  
 //线程池中有多个线程,每一个线程都有tid, 需要一个数组去保存tid 
 pthread_t * tids; //malloc()  
  
 //线程池中正在服役的线程数,当前线程个数 
 unsigned int active_threads; 
  
 //线程池任务队列最大的任务数量 
 unsigned int max_waiting_tasks; 
  
 //线程池任务队列上当前有多少个任务 
 unsigned int cur_waiting_tasks; 
  
 //...... 
 
}; 
 
//任务队列(链表)上面的任务结点,只要能够描述好一个任务就可以了, 
//线程会不断地任务队列取任务 
struct task  //任务结点  
{ 
 // 1. 任务结点表示的任务,“函数指针”指向任务要执行的函数(cp_file) 
 void*(* do_task)(void * arg); 
  
 //2. 指针,指向任务指向函数的参数(文件描述符) 
 void * arg; 
  
 //3. 任务结点类型的指针,指向下一个任务 
 struct task * next; 
}; 

The thread pool framework code is as follows, the functions are filled in by yourself:

Function interfaces required to operate the thread pool: pthread_pool.c, pthread_pool.h

Imagine the "thread pool" as an outsourcing company. What you need to complete is to operate the function interface provided by the thread pool.

pthread_pool.c

#include "pthread_pool.h" 
 
/* 
 init_pool: 线程池初始化函数,初始化指定的线程池中有thread_num个初始线程 
 @pool:指针,指向您要初始化的那个线程池 
 @threa_num: 您要初始化的线程池中开始的线程数量 
 返回值:  
  成功 0 
  失败 -1 
*/ 
 
int init_pool(pthread_pool * pool , unsigned int threa_num) 
{ 
 //初始化线程池的结构体 
  
 //初始化线程互斥锁 
 pthread_mutex_init(&pool->lock, NULL); 
  
 //初始化线程条件变量 
 pthread_cond_init(&pool->cond, NULL); 
 
 pool->shutdown = false ;// 不退出 
 
 pool->task_list = (struct task*)malloc(sizeof(struct task)); 
 
 pool->tids = (pthread_t *)malloc(sizeof(pthread_t) * MAX_ACTIVE_THREADS); 
 if(pool->task_list == NULL || pool->tids == NULL) 
 { 
  perror("malloc memery error"); 
  return -1; 
 } 
 
 pool->task_list->next = NULL; 
 
 //线程池中一开始初始化多少个线程来服役 
 pool->active_threads = threa_num; 
 
 //表示线程池中最多有多少个任务 
 pool->max_waiting_tasks = MAX_WAITING_TASKS; 
 
 //线程池中任务队列当前的任务数量 
 pool->cur_waiting_tasks = 0; 
 
 //创建thread_num个线程,并且让线程去执行任务调配函数, 
 //记录所有线程的tid 
 int i = 0; 
 for(i = 0; i tids)[i], NULL, routine, (void*)pool); 
  if(ret != 0) 
  { 
   perror("create thread error"); 
   return -1; 
  } 
 
  printf("[%lu]:[%s] ===> tids[%d]:[%lu]",pthread_self(), 
   __FUNCTION__, i , pool->tids[i]); 
 } 
 
 return 0; 
} 
 
/* 
 routine: 任务调配函数。 
  所有线程开始都执行此函数,此函数会不断的从线程池的任务队列 
  中取下任务结点,去执行。 
   
  任务结点中包含“函数指针” h "函数参数" 
*/ 
 
void * routine(void * arg) 
{ 
 //arg表示你的线程池的指针 
  
 while() 
 { 
  //获取线程互斥锁,lock  
   
  //当线程池没有结束的时候,不断地从线程池的任务队列取下结点 
  //去执行。 
   
  //释放线程互斥锁,unlock 
   
  //释放任务结点 
 } 
} 
 
/* 
 destroy_pool: 销毁线程池,销毁前要保证所有的任务已经完成 
*/ 
 
int destroy_pool(pthread_pool * pool) 
{ 
 //释放所有空间 等待任务执行完毕(join)。 
 //唤醒所有线程 
 //利用join函数回收每一个线程资源。 
} 
 
/* 
 add_task:给任务队列增加任务, 把do_task指向的任务(函数指针)和 
  arg指向的参数保存到一个任务结点,添加到pool任务队列中。 
   
 @pool : 您要添加任务的线程池 
 @do_task : 您需要添加的任务(cp_file) 
 @arg: 您要执行的任务的参数(文件描述符) 
*/ 
 
int add_task(pthread_pool *pool,void*(* do_task)(void * arg), void*arg) 
{ 
 //把第二个参数和第三个参数封装成struct task  
  
 //再把它添加到 pool->task 任务队列中去 
  
 //注意任务队列是一个共享资源 
  
 //假如任务后要唤醒等待的线程。 
} 
 
//如果任务多的时候,往线程池中添加线程  pthread_create 
int add_threads(pthread_pool * pool, unsigned int num); 
{ 
 //新创建num个线程,让每一个线程去执行线程调配函数 
  
 //将每一个新创建的线程tid,添加到pool-> tids  
} 
 
//如果任务少的时候,减少线程池中线程的数量 pthread_cancel join 
int remove_threads(pthread_pool * pool, unsigned int num) 
{ 
 //用pthread_cancel取消num个线程  
 //利用pthread_join函数去回收资源。 
} 

pthread_pool.h

#ifndef __PTHREAD_POOL_H__ 
#define __PTHREAD_POOL_H__ 
 
//表示线程池中最多有多少个线程 
#define MAX_ACTIVE_THREADS 20 
 
//表示线程池中最多有多少个任务 
#define MAX_WAITING_TASKS 1024 
 
//任务队列(链表)上面的任务结点,只要能够描述好一个任务就可以了, 
//线程会不断地任务队列取任务 
struct task  //任务结点  
{ 
 // 1. 任务结点表示的任务,“函数指针”指向任务要执行的函数(cp_file) 
 void*(* do_task)(void * arg); 
  
 //2. 指针,指向任务指向函数的参数(文件描述符) 
 void * arg; 
  
 //3. 任务结点类型的指针,指向下一个任务 
 struct task * next; 
}; 
 
struct pthread_pool //线程池的实现 
{ 
 //一般会有如下成员 
 
 //互斥锁,用来保护这个“任务队列” 
 pthread_mutex_t lock; //互斥锁  
  
 //线程条件变量 表示“任务队列”是否有任务 
 pthread_cond_t cond; //条件变量 
  
 bool shutdown; //表示是否退出程序 bool:类型 false / true 
 
 //任务队列(链表),指向第一个需要指向的任务 
 //所有的线程都从任务链表中获取任务 "共享资源" 
 struct task * task_list; 
  
 //线程池中有多个线程,每一个线程都有tid, 需要一个数组去保存tid 
 pthread_t * tids; //malloc()  
  
 //线程池中正在服役的线程数,当前线程个数 
 unsigned int active_threads; 
  
 //线程池任务队列最大的任务数量 
 unsigned int max_waiting_tasks; 
  
 //线程池任务队列上当前有多少个任务 
 unsigned int cur_waiting_tasks; 
  
 //...... 
 
}; 
 
/* 
 init_pool: 线程池初始化函数,初始化指定的线程池中有thread_num 
  个初始线程 
 @pool:指针,指向您要初始化的那个线程池 
 @threa_num: 您要初始化的线程池中开始的线程数量 
 返回值:  
  成功 0 
  失败 -1 
*/ 
 
int init_pool(pthread_pool * pool , unsigned int threa_num); 
 
/* 
 routine: 任务调配函数。 
  所有线程开始都执行此函数,此函数会不断的从线程池的任务队列 
  中取下任务结点,去执行。 
   
  任务结点中包含“函数指针” h "函数参数" 
*/ 
 
void * routine(void * arg); 
 
/* 
 destroy_pool: 销毁线程池,销毁前要保证所有的任务已经完成 
*/ 
 
int destroy_pool(pthread_pool * pool); 
 
/* 
 add_task:给任务队列增加任务, 把do_task指向的任务(函数指针)和 
  arg指向的参数保存到一个任务结点,添加到pool任务队列中。 
   
 @pool : 您要添加任务的线程池 
 @do_task : 您需要添加的任务(cp_file) 
 @arg: 您要执行的任务的参数(文件描述符) 
*/ 
 
int add_task(pthread_pool *pool,void*(* do_task)(void * arg), void*arg); 
 
//如果任务多的时候,往线程池中添加线程  pthread_create 
int add_threads(pthread_pool * pool, unsigned int num); 
 
 
//如果任务少的时候,减少线程池中线程的数量 pthread_cancel join 
int remove_threads(pthread_pool * pool, unsigned int num); 
 
#endif 

The above is the detailed content of The use of thread pool under Linux C. For more information, please follow other related articles on the PHP Chinese website!

Statement
This article is reproduced at:良许Linux教程网. If there is any infringement, please contact admin@php.cn delete
What are the main tasks of a Linux system administrator?What are the main tasks of a Linux system administrator?Apr 19, 2025 am 12:23 AM

The main tasks of Linux system administrators include system monitoring and performance tuning, user management, software package management, security management and backup, troubleshooting and resolution, performance optimization and best practices. 1. Use top, htop and other tools to monitor system performance and tune it. 2. Manage user accounts and permissions through useradd commands and other commands. 3. Use apt and yum to manage software packages to ensure system updates and security. 4. Configure a firewall, monitor logs, and perform data backup to ensure system security. 5. Troubleshoot and resolve through log analysis and tool use. 6. Optimize kernel parameters and application configuration, and follow best practices to improve system performance and stability.

Is it hard to learn Linux?Is it hard to learn Linux?Apr 18, 2025 am 12:23 AM

Learning Linux is not difficult. 1.Linux is an open source operating system based on Unix and is widely used in servers, embedded systems and personal computers. 2. Understanding file system and permission management is the key. The file system is hierarchical, and permissions include reading, writing and execution. 3. Package management systems such as apt and dnf make software management convenient. 4. Process management is implemented through ps and top commands. 5. Start learning from basic commands such as mkdir, cd, touch and nano, and then try advanced usage such as shell scripts and text processing. 6. Common errors such as permission problems can be solved through sudo and chmod. 7. Performance optimization suggestions include using htop to monitor resources, cleaning unnecessary files, and using sy

What is the salary of Linux administrator?What is the salary of Linux administrator?Apr 17, 2025 am 12:24 AM

The average annual salary of Linux administrators is $75,000 to $95,000 in the United States and €40,000 to €60,000 in Europe. To increase salary, you can: 1. Continuously learn new technologies, such as cloud computing and container technology; 2. Accumulate project experience and establish Portfolio; 3. Establish a professional network and expand your network.

What is the main purpose of Linux?What is the main purpose of Linux?Apr 16, 2025 am 12:19 AM

The main uses of Linux include: 1. Server operating system, 2. Embedded system, 3. Desktop operating system, 4. Development and testing environment. Linux excels in these areas, providing stability, security and efficient development tools.

Does the internet run on Linux?Does the internet run on Linux?Apr 14, 2025 am 12:03 AM

The Internet does not rely on a single operating system, but Linux plays an important role in it. Linux is widely used in servers and network devices and is popular for its stability, security and scalability.

What are Linux operations?What are Linux operations?Apr 13, 2025 am 12:20 AM

The core of the Linux operating system is its command line interface, which can perform various operations through the command line. 1. File and directory operations use ls, cd, mkdir, rm and other commands to manage files and directories. 2. User and permission management ensures system security and resource allocation through useradd, passwd, chmod and other commands. 3. Process management uses ps, kill and other commands to monitor and control system processes. 4. Network operations include ping, ifconfig, ssh and other commands to configure and manage network connections. 5. System monitoring and maintenance use commands such as top, df, du to understand the system's operating status and resource usage.

Boost Productivity with Custom Command Shortcuts Using Linux AliasesBoost Productivity with Custom Command Shortcuts Using Linux AliasesApr 12, 2025 am 11:43 AM

Introduction Linux is a powerful operating system favored by developers, system administrators, and power users due to its flexibility and efficiency. However, frequently using long and complex commands can be tedious and er

What is Linux actually good for?What is Linux actually good for?Apr 12, 2025 am 12:20 AM

Linux is suitable for servers, development environments, and embedded systems. 1. As a server operating system, Linux is stable and efficient, and is often used to deploy high-concurrency applications. 2. As a development environment, Linux provides efficient command line tools and package management systems to improve development efficiency. 3. In embedded systems, Linux is lightweight and customizable, suitable for environments with limited resources.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

MantisBT

MantisBT

Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

Dreamweaver Mac version

Dreamweaver Mac version

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools