【p2p、分布式,区块链笔记 UPNP】: Libupnp的线程池简述

  • 线程池在网络编程中是一个关键的组成部分,尤其是处理高并发请求时,线程池可以显著提高系统的性能和资源利用效率。它的关键组成部分包括以下几个要素:
  • 任务队列:一个(或多个)用于存放待执行任务的队列。任务通常以函数指针或任务对象的形式存储在队列中。
  • 生产者: 负责生成任务并将任务提交到线程池的任务队列中。
  • 消费者: 从任务队列中获取任务并进行处理。

线程池结构

typedef struct THREADPOOL
{
       
    FreeList jobFreeList;                /*! 任务的空闲列表。 */
    LinkedList lowJobQ;                  /*! 低优先级任务队列。 */
    LinkedList medJobQ;                  /*! 中等优先级任务队列。 */
    LinkedList highJobQ;                 /*! 高优先级任务队列。 */
    ThreadPoolJob *persistentJob;        /*! 持久任务。 */

    ithread_mutex_t mutex;              /*! 保护任务队列的互斥锁。*/
    ithread_cond_t condition;           /*! 用于任务队列信号的条件变量。*/
    ithread_cond_t start_and_shutdown;  /*! 用于启动和关闭的条件变量。 */
    
    // 该变量只在 创建消费者线程CreateWorker 时使用,为1时阻塞其他线程,创建完成后通过start_and_shutdown通知其他继续运行
    int pendingWorkerThreadStart;       /*! 是否在等待新工作线程启动。 */
    
    int lastJobId;                      /*! 任务ID计数器。 */
    int shutdown;                       /*! 标识线程池是否正在关闭。 */
    int totalThreads;                   /*! 线程总数。 */
    int busyThreads;                    /*! 当前正在执行任务的线程数量。 */
    int persistentThreads;              /*! 持久线程的数量。 */
    ThreadPoolAttr attr;                /*! 线程池的属性。 */
    ThreadPoolStats stats;              /*! 统计数据。 */
} ThreadPool;

线程池的任务队列结构(以LINKEDLIST 为例)

  • LINKEDLIST :生产者和消费者共同操作的任务队列,线程池中一般存在多个生产者和多个消费者(共同push、pop),所以操作时要加锁。
  • LinkedList.h中也定义了链表的创建(ListInit)、插入(ListAddTail)和删除 (ListDelNode)函数。
  • 另外需要注意的是,当void *ListDelNode(LinkedList *list, ListNode *dnode, int freeItem)的freeItem == 0,则节点中的项会从链表中移除但不会被释放。其地址作为函数的返回值。
/*!
 * 如果 head->next = tail,那么链表为空。
 *
 * 要遍历链表,可以使用如下代码:
 *  LinkedList g;ListNode *temp = NULL;for (temp = ListHead(g); temp != NULL; temp = ListNext(g, temp)) {}
 */
typedef struct LINKEDLIST {
	ListNode head; // 链表的头节点,实际第一个数据节点存储在 head->next 中
	ListNode tail; // 链表的尾节点,实际最后一个数据节点存储在 tail->prev 中
	long size; // 链表的当前大小(节点个数)

	FreeList freeNodeList;  // 空闲节点列表,用于回收和重用内存
	free_function free_func; // 释放节点时使用的函数指针,ListInit时确定
	cmp_routine cmp_func; // 比较两个节点数据时使用的函数指针
} LinkedList;
ListNode
typedef struct LISTNODE {
    struct LISTNODE *prev;  // 指向前一个节点的指针
    struct LISTNODE *next;  // 指向下一个节点的指针
    void *item;             // 指向节点中存储的通用数据(任意类型的项,当前示例为指向ThreadPoolJob的指针)
} ListNode;
  • 下面的例子中highJobQ的head为ListNode类型,其中的item为ThreadPoolJob类型
// https://github1s.com/pupnp/pupnp/blob/branch-1.14.x/upnp/src/threadutil/ThreadPool.c#L547-L556
// 依次尝试从高、中、低优先级队列中取作业
				if (tp->highJobQ.size > 0) {
					head = ListHead(&tp->highJobQ);
					if (head == NULL) {
						tp->stats.workerThreads--;
						goto exit_function;
					}
					job = (ThreadPoolJob *)head->item;
					CalcWaitTime(tp, HIGH_PRIORITY, job);
					ListDelNode(&tp->highJobQ, head, 0);
ThreadPoolJob
/*! Internal ThreadPool Job. */
typedef struct THREADPOOLJOB
{
	start_routine func;
	void *arg;
	free_routine free_func;
	struct timeval requestTime;
	ThreadPriority priority;
	int jobId;
} ThreadPoolJob;

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值