首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

linux 下c语言简单实现线程池

基础概念

线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池可以有效地控制系统中并发线程的数量,避免大量线程之间的切换所带来的性能开销。

优势

  1. 减少线程创建和销毁的开销:线程池中的线程可以重复利用,避免了频繁创建和销毁线程的开销。
  2. 提高响应速度:任务可以立即执行,无需等待新线程的创建。
  3. 便于管理:可以统一管理和控制线程的数量,避免系统资源被过度消耗。

类型

  1. 固定大小的线程池:线程池的大小是固定的,一旦创建,线程的数量不会改变。
  2. 可缓存的线程池:线程池的大小是可变的,根据需要创建新的线程,空闲一段时间后回收线程。
  3. 单线程线程池:只包含一个工作线程,保证所有任务按顺序执行。

应用场景

  • 服务器程序:处理大量并发请求。
  • 后台任务处理:如定时任务、批处理任务等。
  • Web应用:处理HTTP请求。

实现示例

以下是一个简单的Linux下C语言实现线程池的示例:

代码语言:txt
复制
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define NUM_THREADS 5

typedef struct {
    void (*function)(void *);
    void *argument;
} thread_pool_task;

typedef struct {
    thread_pool_task *tasks;
    int task_count;
    int task_size;
    pthread_mutex_t lock;
    pthread_cond_t cond;
} thread_pool;

void *thread_pool_worker(void *arg) {
    thread_pool *pool = (thread_pool *)arg;
    while (1) {
        pthread_mutex_lock(&pool->lock);
        while (pool->task_count == 0) {
            pthread_cond_wait(&pool->cond, &pool->lock);
        }
        thread_pool_task task = pool->tasks[--pool->task_count];
        pthread_mutex_unlock(&pool->lock);
        task.function(task.argument);
    }
    return NULL;
}

void thread_pool_init(thread_pool *pool, int task_size) {
    pool->tasks = malloc(task_size * sizeof(thread_pool_task));
    pool->task_count = 0;
    pool->task_size = task_size;
    pthread_mutex_init(&pool->lock, NULL);
    pthread_cond_init(&pool->cond, NULL);
    for (int i = 0; i < NUM_THREADS; ++i) {
        pthread_t thread;
        pthread_create(&thread, NULL, thread_pool_worker, pool);
        pthread_detach(thread);
    }
}

void thread_pool_add_task(thread_pool *pool, void (*function)(void *), void *argument) {
    pthread_mutex_lock(&pool->lock);
    if (pool->task_count == pool->task_size) {
        pool->task_size *= 2;
        pool->tasks = realloc(pool->tasks, pool->task_size * sizeof(thread_pool_task));
    }
    pool->tasks[pool->task_count++] = (thread_pool_task){function, argument};
    pthread_cond_signal(&pool->cond);
    pthread_mutex_unlock(&pool->lock);
}

void example_task(void *arg) {
    int *num = (int *)arg;
    printf("Task %d is running\n", *num);
}

int main() {
    thread_pool pool;
    thread_pool_init(&pool, 10);

    for (int i = 0; i < 20; ++i) {
        int *arg = malloc(sizeof(int));
        *arg = i;
        thread_pool_add_task(&pool, example_task, arg);
    }

    sleep(1); // 等待任务完成
    free(pool.tasks);
    pthread_mutex_destroy(&pool->lock);
    pthread_cond_destroy(&pool->cond);
    return 0;
}

参考链接

常见问题及解决方法

  1. 线程池中的任务执行顺序
    • 问题:任务可能不会按照添加的顺序执行。
    • 原因:线程池中的多个线程并发执行任务,任务的执行顺序无法保证。
    • 解决方法:如果需要保证任务按顺序执行,可以使用单线程线程池或者在任务函数中添加同步机制。
  • 线程池资源耗尽
    • 问题:当任务数量超过线程池的最大容量时,新的任务无法添加。
    • 原因:线程池的任务队列已满。
    • 解决方法:动态调整任务队列的大小,或者在添加任务时进行检查,避免任务过多导致资源耗尽。
  • 线程池中的线程死锁
    • 问题:线程池中的线程可能因为资源竞争而死锁。
    • 原因:多个线程互相等待对方释放资源。
    • 解决方法:合理设计任务和资源的使用,避免循环等待的情况发生。

通过以上示例和解释,希望你能更好地理解Linux下C语言实现线程池的基础概念、优势、类型、应用场景以及常见问题及解决方法。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

C语言实现线程池

C语言标准库中并没有提供线程池的实现,线程池需要手搓 实现线程池的基本思路是:先创建几个固定的线程,让每个线程运行起来,然后通过互斥锁和条件变量使得每个线程进入等待状态,当需要分派线程时,改变条件变量,...同时实现了一个队列来存储需要执行的任务。 Task结构体用于表示线程池需要执行的任务,包括属性函数指针和函数参数。...,包括内嵌实现的队列,用的是循环索引数组模拟实现的队列,互斥锁和条件变量,固定大小的线程组,还有一个是否销毁线程池的标记。...int shutdown; // 是否销毁线程池 } ThreadPool; 初始化线程池,创建POOLSIZE个线程,创建日志文件,初始化互斥锁和条件变量。...,设置线程池销毁标记,等待所有线程结束后释放线程内存,并销毁互斥锁和条件变量。

50610
  • Linux下精简线程池的实现

    线程清理函数 3. 结构 4. 遇到的问题 5. 代码 6. 待解决 7. 其他 8. 参考 在Linux下使用C++调用pthread API实现的一个线程池。...简介 这个线程池是在学习完《Linux/UNIX系统编程手册》中线程相关知识后用来练手的小项目,线程相关函数都是直接调用Linux的API,并且使用了C++中的queue和vector。...这样就保证当不允许多次加锁时不会出现最简单情况下的死锁。 PTHREAD_MUTEX_ADAPTIVE_NP 适应锁,动作最简单的锁类型,仅等待解锁后重新竞争。...中的线程池 用C++写线程池是怎样一种体验?...基于c++11的100行实现简单线程池 使用C++11实现线程池的两种方法 欢迎与我分享你的看法。 转载请注明出处:http://taowusheng.cn/

    1.8K30

    C++线程池实现_java线程池状态

    在计算机程序中,线程是一种很重要的资源,使用的恰当可以极大的提高程序的效率,也就是多线程的使用,但是多线程会让应用程序变得异常复杂,会占用大量的系统资源。...在这种情况下,多线程变得不太合适了,那么什么机制适用于这种情况下呢,这就是线程池。...通常情况下,应用程序中采用异步调用函数的形式来实现多任务,在windows中,系统提供了QueueUserWorkItem函数实现异步调用,这个函数相当于在线程池中建立多个用户工作项目,跟普通线程机制一样...,线程池也有线程的同步等机制。...下面实现了一个简单的线程池程序,没有什么大的功能,可以看到线程池的用法。

    78410

    【Linux多线程】线程池的实现

    1.1 为什么需要线程池 在多线程编程中,每次创建和销毁线程都需要操作系统分配和回收资源,这会带来较大的系统开销,尤其是在高并发场景下,频繁创建和销毁线程会严重影响性能。...实现简易线程池 2.1 需求分析 实现线程池的目的是什么? 利用一个类来管理一批线程来执行任务,这个类就是线程池。 这个线程池应该具有什么属性?...上的线程池还是太简单了,如果你只是想了解简单的线程池的思想,上面也差不多。 下面,我们将一步步将线程池提升到完美。 3....实现封装版本线程池 先封装一个线程库 #pragma once // 封装线程库 #include #include #include #...引入生产消费者模型的线程池 从任务队列入手,开始引入生产消费者模型,同时引入RAII风格的锁,实现自动化加锁与解锁。

    14010

    手写线程池 - C语言版

    线程池原理 我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题:如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,...线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。如果某个线程在托管代码中空闲(如正在等待某个事件), 则线程池将插入另一个辅助线程来使所有处理器保持繁忙。...如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间后创建另一个辅助线程但线程的数目永远不会超过最大值。超过最大值的线程可以排队,但他们要等到其他线程完成后才启动。...在各个编程语言的语种中都有线程池的概念,并且很多语言中直接提供了线程池,作为程序猿直接使用就可以了,下面给大家介绍一下线程池的实现原理: 线程池的组成主要分为 3 个部分,这三部分配合工作就可以得到一个完整的线程池...: 任务队列,存储需要处理的任务,由工作的线程来处理这些任务 通过线程池提供的 API 函数,将一个待处理的任务添加到任务队列,或者从任务队列中删除 已处理的任务会被从任务队列中删除 线程池的使用者,也就是调用线程池函数往任务队列中添加任务的线程就是生产者线程

    1.9K30

    使用 C 语言开发一个简单的线程池函数

    线程池的概念线程池顾名思义就是一个池子,里边放着很多的线程,那么这么做有什么好处。试想一下,如果我们家里有很多工具,比方说剪刀,斧头,如果我们每次用剪刀后都扔了。...仔细想一下,我们的一个简单想法就是用链表保存一系列线程,然后用链表保存一系列处理线程的对象。所有我们就有以下结构。...这里岔开一下,因为这里涉及双向链表管理,所有我们先定义两个链表操作,因为本身比较简单,就只用宏定义,开发中可以自己开发函数。...最后就是线程池怎么销毁,简单说就是部门全部裁掉。...至此一个简单的线程池函数就创建完毕了。开发工程上的技术大多都是有其目的的,各种封装越来越好的技术确实难以理解,但是我们知道他是干什么的,再了解他是怎么干的,最后简单写一个会更好。

    19910

    简单线程池的实现

    线程池的核心就是,当接收到一个任务,需要一个线程去执行时,并不着急创建一个线程,而是先去线程池检查是否有空闲的线程,如果有,则直接使用,如果没有则创建新的线程,然后执行任务。...任务执行完成后,也不着急销毁线程,而是将线程放到线程池的空闲队列中,等待下次使用。 首先是线程池的实现。...首先是线程池的实现: /** * Created by Joker on 2015/3/7. */ public class ThreadPool { private static ThreadPool...static class SingleTonHolder { private static ThreadPool threadPool = new ThreadPool(); } /*单例获得线程池实例...该工作线程的实现如下: /** * Created by Joker on 2015/3/7. */ public class JThread extends Thread { //线程池 private

    39810

    Linux C下线程池的使用

    线程池本质上也是一个数据结构,需要一个结构体去描述它: struct pthread_pool //线程池的实现 { //一般会有如下成员 //互斥锁,用来保护这个“任务队列” pthread_mutex_t...任务结点类型的指针,指向下一个任务 struct task * next; }; 线程池框架代码如下,功能自填: 操作线程池所需要的函数接口:pthread_pool.c 、pthread_pool.h...把“线程池”想象成一个外包公司,你需要去完成的就是操作线程池所提供的函数接口。...pthread_pool.c #include "pthread_pool.h" /* init_pool: 线程池初始化函数,初始化指定的线程池中有thread_num个初始线程 @pool:指针...任务结点类型的指针,指向下一个任务 struct task * next; }; struct pthread_pool //线程池的实现 { //一般会有如下成员 //互斥锁,用来保护这个“

    1.8K50

    C++ 线程池的实现(上)

    引言 最近工作开始使用C++,于是想用C++实现一个线程池。这里就分两篇文章来记录一下实现的过程,本篇主要为理论篇,具体的实践篇,等代码功能稳定以后再总结。 2....简介 本部分从线程池作用到线程池的原理介绍。想要实现具体的线程池,需要先知道线程池有什么作用,然后再去学习他的原理,最终用代码实现出来。...在线程池中只存在几个固定的线程,由线程池来维护,等待调度器派发已存在空闲的线程去执行对应的任务。 由此,便实现了线程的一次创建多次使用的功能,从而避免了短时间内的任务时创建与销毁线程的代价。...线程池不仅能保护资源的充分利用,还能保证不被过分调度。 线程池的原理 线程池的在初始化时,会先创建固定数量的线程;具体的任务会放在任务队列中,类似于生产者-消费者概念。...如此反复便实现了,多个任务并发的执行。 ? 线程池原理.png 3 总结 本篇文章简单记录一下线程池的作用及原理,后续文章会记录具体的代码实现。

    1.5K20

    【Java】实现一个简单的线程池

    一、线程池的模式 线程池顾名思义就是管理线程的一个池子,我们把创建线程的过程交给线程池来处理,而这个线程池当中的线程都会从阻塞队列当中取获取任务执行。...我们不在直接把任务的创建过程写到我们初始化的线程对象中,而是通过调用线程池的execute()方法,同时把我们的具体任务交作为参数传给线程池,之后线程池就会把任务添加到阻塞队列当中,而线程池当中的线程会从阻塞队列当中获取任务并执行...三、代码实现 因为我们只是简单的实现,所以有一些情况和实际不太相似。...就是任务添加不进去或者取不出来的时候,线程会被一直挂起。真实并不是如此,这里只是简单的展示。 阻塞队列需要的就是这两个存取的过程。 2.ThreadPool 先看看线程池当中的属性。...这个Worker对象实现了Runnable接口,我们可以把这个类当作线程类,这个类中有一个task属性,因为我们线程池当中的线程是要获取任务执行的,这个任务就用这个task属性代表。

    15810

    C语言链表应用--基于Linux C多线程软件框架实现

    之前写过一篇基于C语言链表实现的工作任务注册与执行,链接如下: https://blog.csdn.net/morixinguan/article/details/77986553 后面使用它演变成为了另外一个框架...,也就是多线程,当时的设计思路主要是为了服务测试程序。...搞过RK(瑞芯微)平台的都知道,这个平台提供了一个PCBA的测试程序,它是基于Linux内核链表框架实现的,但该程序有一点不好的地方就在于框架用起来不是那么的简单,因此我针对该项目做了自己的优化,使之用起来简单...RK PCBA实现效果如下: https://wenku.baidu.com/view/09257cb777a20029bd64783e0912a21615797f58.html 我实现的项目具体的数据类型以及数据结构如下...s32 Run_Priority_work(_work handler,s32 direction,const s32 work_array_size) ; #endif //__WORK_H work.c

    2.4K50
    领券