Linux C 实现一个简单的线程池
线程池的定义
线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有处理器保持繁忙。如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间后创建另一个辅助线程但线程的数目永远不会超过最大值。超过最大值的线程可以排队,但他们要等到其他线程完成后才启动。
什么时候需要创建线程池呢?
简单的说,如果一个应用需要频繁的创建和销毁线程,而任务执行的时间又非常短,这样线程创建和销毁的带来的开销就不容忽视,这时也是线程池该出场的机会了。如果线程创建和销毁时间相比任务执行时间可以忽略不计,则没有必要使用线程池了。
实现程序(未完成相关资源的释放操作)
/********************
Pthread Pool
14/06/18 22:06
********************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>
#include <pthread.h>
/* 任务节点结构 */
typedef struct node {
void (*func)(void *arg);
unsigned int *work_id;
struct node *next;
}TaskNode;
/* 线程池结构 */
typedef struct {
pthread_cond_t ready;
pthread_mutex_t lock;
struct node *task_head;
pthread_t *thread_id;
unsigned int cur_queue_size;
}PthreadPool;
static PthreadPool *pool = NULL;
/* 定义线程 */
void *thread_routine (void *arg)
{
while(1)
{
pthread_mutex_lock(&pool->lock);
if(!pool->cur_queue_size){
printf("Thread is waiting .... \n");
pthread_cond_wait(&pool->ready, &pool->lock);
}
pool->cur_queue_size--;
TaskNode *worker = pool->task_head;
pool->task_head= worker->next;
pthread_mutex_unlock (&(pool->lock));
/* 调用函数,执行任务 */
worker->func(worker->work_id);
free (worker);
worker = NULL;
}
}
static void system_init ()
{
int i = 0;
pool = (PthreadPool*) malloc(sizeof(PthreadPool));
/* 初始化锁与条件变量 */
pthread_mutex_init (&pool->lock, NULL);
pthread_cond_init (&pool->ready, NULL);
/* 在池中加入 3 个线程 */
pool->thread_id = (pthread_t*) malloc(3 * sizeof(PthreadPool));
pool->cur_queue_size = 0;
pool->task_head= NULL;
for(; i<3; i++)
pthread_create(&pool->thread_id[i], NULL, thread_routine, NULL);
}
/* 添加任务 */
int pool_add_work (void (*process)(void *arg), unsigned int *id)
{
TaskNode *new_work = (TaskNode*) malloc(sizeof(TaskNode));
new_work->func = process;
new_work->work_id = id;
new_work->next = NULL;
pool->cur_queue_size++;
TaskNode *temp = pool->task_head;
if(!temp)
pool->task_head = new_work;
else{
while(temp->next)
temp = temp->next;
temp->next = new_work;
}
pthread_cond_signal(&pool->ready);
}
/* 定义用户任务 */
void my_process(void *arg)
{
printf ("threadid is 0x%x, working on task %d \n", pthread_self(), *(int *)arg);
sleep (1);
}
int main()
{
unsigned int work_id[10];
int i = 0;
system_init();
/* 等待线程运行 */
sleep(1);
for(; i<10; i++){
work_id[i] = i;
pool_add_work(my_process, &work_id[i]);
}
/* 等待任务执行完毕 */
sleep(5);
return 0;
}
Linux 上编译后,运行结果:
参考自:blog.csdn.net/zouxinfox/article/details/3560891
Linux C 实现一个简单的线程池的更多相关文章
- linux网络编程-一个简单的线程池(41)
有时我们会需要大量线程来处理一些相互独立的任务,为了避免频繁的申请释放线程所带来的开销,我们可以使用线程池 1.线程池拥有若干个线程,是线程的集合,线程池中的线程数目有严格的要求,用于执行大量的相对短 ...
- Linux C 一个简单的线程池程序设计
最近在学习linux下的编程,刚开始接触感觉有点复杂,今天把线程里比较重要的线程池程序重新理解梳理一下. 实现功能:创建一个线程池,该线程池包含若干个线程,以及一个任务队列,当有新的任务出现时,如果任 ...
- linux网络编程之简单的线程池实现
转眼间离15年的春节越来越近了,还有两周的工作时间貌似心已经不在异乡了,期待与家人团聚的日子,当然最后两周也得坚持站好最后一班岗,另外期待的日子往往是心里不能平静的,越是想着过年,反而日子过得越慢,于 ...
- Java一个简单的线程池实现
线程池代码 import java.util.List; import java.util.Vector; public class ThreadPool { private static ...
- 【C/C++开发】C++实现简单的线程池
C++实现简单的线程池 线程池编程简介: 在我们的服务端的程序中运用了大量关于池的概念,线程池.连接池.内存池.对象池等等.使用池的概念后可以高效利用服务器端的资源,比如没有大量的线程在系统中进行上下 ...
- (转)如何在Linux中统计一个进程的线程数
如何在Linux中统计一个进程的线程数 原文:http://os.51cto.com/art/201509/491728.htm 我正在运行一个程序,它在运行时会派生出多个线程.我想知道程序在运行时会 ...
- Java网络与多线程系列之1:实现一个简单的对象池
前言 为什么要从对象池开始呢,先从一个网络IO操作的demo说起 比如下面这段代码,显而易见已经在代码中使用了一个固定大小的线程池,所以现在的重点在实现Runnble接口的匿名对象上,这个对象每次创建 ...
- 简单C++线程池
简单C++线程池 Java 中有一个很方便的 ThreadPoolExecutor,可以用做线程池.想找一下 C++ 的类似设施,尤其是能方便理解底层原理可上手的.网上找到的 demo,基本都是介绍的 ...
- ExecutorService 建立一个多线程的线程池的步骤
ExecutorService 建立一个多线程的线程池的步骤: 线程池的作用: 线程池功能是限制在系统中运行的线程数. 依据系统的环境情况,能够自己主动或手动设置线程数量.达到执行的最佳效果:少了浪费 ...
随机推荐
- IO模型的介绍
Stevens 在文章中的一种IO Model: ****blocking IO #阻塞 IO (系统调用不返回结果并让当前线程一直阻塞,只有当该系统调用获得结果或者超时出错才返回) *** ...
- Base64格式上传文件至阿里云(java)
Controller @PostMapping("/save") public R save(@RequestBody ShareEntity share){ OSSClient ...
- 关于Podfile,某个第三方指定源
项目中有个指定了源,摸索好久Podfile编写方式,网上都没有 pod 'SDK名字', :source => '指定源' 其他的直接按原来的就可以了
- python之常用模块4
pyinotify模块 pip3 install pyinotify pyinotify提供的事件: 事件标志 事件含义 IN_ACCESS 被监控项目或者被监控目录中的文件被访问,比如一个文件被读取 ...
- 记一个centos分区大小调整过程
1. 备份 /home 目录 [root@centos ~]# cp -r /home /home_backup 2. 查看目前磁盘使用的情况, 需要将 /dev/mapper/centos-home ...
- [转]Kaldi命令词识别
转自: http://www.jianshu.com/p/5b19605792ab?utm_campaign=maleskine&utm_content=note&utm_medium ...
- 前端开发JS白板编程题目若干
在前端开发参加面试的时候,无论是校招还是社招,往往都会碰到让我们直接在白纸或者白板上手撸代码的题目.由于是手撸代码,这些题目肯定不会过于复杂和冗长,否则面试那么一小会时间根本写不完.本文总结了几个我本 ...
- express使用记录
express使用记录 文章用啥写?→→ VsCode. 代码用啥写?→→ VsCode. 编辑器下载:VsCode 一.windows下安装node.js环境: 下载地址 相比以前搭过的服务端语言的 ...
- python模块的导入的两种方式区别详解
Python 有两种导入模块的方法.两种都有用,你应该知道什么时候使用哪一种方法.一种方法,import module,另一种是from module import,下面是 from module i ...
- Ubuntu 16.04下Samba服务器搭建和配置(配截图)
一.相关介绍 Samba是在Linux和UNIX系统上实现SMB协议的一个免费软件,由服务器及客户端程序构成.SMB(Server Messages Block,信息服务块)是一种在局域网上共享文件和 ...