【p2p、分布式,区块链笔记 UPNP】: Libupnp test_init.c 03 初始化SDK --- 线程池初始化(UpnpInitThreadPools)

  • 线程池初始化相关代码声明在https://github1s.com/pupnp/pupnp/blob/branch-1.14.x/upnp/src/threadutil/ThreadPool.h。线程池配置相关代码位置:https://github1s.com/pupnp/pupnp/blob/branch-1.14.x/upnp/src/inc/config.h#L76-L105

相关数据结构:

  • 以下是代码中几个主要结构体的作用说明,它们涉及线程池的配置、任务和统计等功能:
    • ThreadPoolAttr 用于配置线程池的属性,如线程的最小、最大数量,空闲时间等。
    • ThreadPoolJob 定义了线程池中的任务,包括任务的执行函数、参数和优先级。
    • ThreadPoolStats 用于记录线程池的统计信息,如任务执行时间、任务队列情况等。
    • ThreadPool 是线程池的核心结构,管理线程、任务队列以及线程池的运行状态。
/*! 线程池的属性。用于设置和修改线程池的参数。 */
typedef struct THREADPOOLATTR
{
   
   
    /*! 线程池始终至少保持这个数量的线程。 */
    int minThreads;
    /*! 线程池的线程数永远不会超过此数量。 */
    int maxThreads;
    /*! 分配给每个线程的最小栈大小。 */
    size_t stackSize;
    /*! 线程在终止前保持空闲的最长时间(以毫秒为单位)。 */
    int maxIdleTime;
    /*! 每个线程维护的任务数。 */
    int jobsPerThread;
    /*! 总共可以排队的最大任务数量。 */
    int maxJobsTotal;
    /*! 低优先级或中等优先级的任务在被提升优先级之前的等待时间(以毫秒为单位)。 */
    int starvationTime;
    /*! 使用的调度策略。 */
    PolicyType schedPolicy;
} ThreadPoolAttr;

/*! 内部线程池任务。 */
typedef struct THREADPOOLJOB
{
   
   
    start_routine func;       // 任务的执行函数
    void *arg;                // 传递给任务函数的参数
    free_routine free_func;   // 释放资源的回调函数
    struct timeval requestTime;  // 任务请求的时间
    ThreadPriority priority;  // 任务优先级
    int jobId;                // 任务ID
} ThreadPoolJob;

/*! 用于存储统计数据的结构体。 */
typedef struct TPOOLSTATS
{
   
   
    double totalTimeHQ;    // 高优先级任务的总处理时间
    int totalJobsHQ;       // 已处理的高优先级任务总数
    double avgWaitHQ;      // 高优先级任务的平均等待时间
    double totalTimeMQ;    // 中等优先级任务的总处理时间
    int totalJobsMQ;       // 已处理的中等优先级任务总数
    double avgWaitMQ;      // 中等优先级任务的平均等待时间
    double totalTimeLQ;    // 低优先级任务的总处理时间
    int totalJobsLQ;       // 已处理的低优先级任务总数
    double avgWaitLQ;      // 低优先级任务的平均等待时间
    double totalWorkTime;  // 总工作时间
    double totalIdleTime;  // 总空闲时间
    int workerThreads;     // 工作线程的数量
    int idleThreads;       // 空闲线程的数量
    int persistentThreads; // 持久线程的数量
    int totalThreads;      // 线程总数
    int maxThreads;        // 最大线程数量
    int currentJobsHQ;     // 当前高优先级任务数
    int currentJobsLQ;     // 当前低优先级任务数
    int currentJobsMQ;     // 当前中等优先级任务数
} ThreadPoolStats;

/*!
 * \brief 一个类似于 UPnP SDK 中的线程池。
 *
 * 允许线程池中的线程调度和运行任务。线程池初始化时设置了最小和最大线程数、
 * 最大空闲时间以及每线程的任务比率。如果一个工作线程在最大空闲时间内未接收到任务,
 * 且当前线程池的运行线程数超过最小线程数,则该工作线程将退出。如果调度任务时,
 * 当前任务与线程的比率超过设定比率,且线程池的线程数少于最大值,则将创建一个新线程。
 */
typedef struct THREADPOOL
{
   
   
    /*! 保护任务队列的互斥锁。是对pthread_mutex_t(🔒对象)的封装 */
    ithread_mutex_t mutex;
    /*! 用于任务队列信号的条件变量。条件变量是一种允许线程等待特定条件的机制,直到满足某些条件才允许线程在访问共享资源之前进行访问,线程被唤醒,重新获取互斥锁并继续执行。https://blog.youkuaiyun.com/ResumeProject/article/details/129522548 */
    ithread_cond_t condition;
    /*! 用于启动和关闭的条件变量。 */
    ithread_cond_t start_and_shutdown;
    /*! 任务ID计数器。 */
    int lastJobId;
    /*! 标识线程池是否正在关闭。 */
    int shutdown;
    /*! 线程总数。 */
    int totalThreads;
    /*! 是否在等待新工作线程启动。 */
    int pendingWorkerThreadStart;
    /*! 当前正在执行任务的线程数量。 */
    int busyThreads;
    /*! 持久线程的数量。 */
    int persistentThreads;
    /*! 任务的空闲列表。 */
    FreeList jobFreeList;
    /*! 低优先级任务队列。 */
    LinkedList lowJobQ;
    /*! 中等优先级任务队列。 */
    LinkedList medJobQ;
    /*! 高优先级任务队列。 */
    LinkedList highJobQ;
    /*! 持久任务。 */
    ThreadPoolJob *persistentJob;
    /*! 线程池的属性。 */
    ThreadPoolAttr attr;
    /*! 统计数据。 */
    ThreadPoolStats stats;
} ThreadPool;

UpnpInitThreadPools

  • UpnpInitThreadPools()(无参数)为预初始化直接调用的函数。
/*!
 * \brief Initializes the global threadm pools used by the UPnP SDK.
 *
 * \return UPNP_E_SUCCESS on success or UPNP_E_INIT_FAILED if a mutex could not
 * 	be initialized.
 */
static int UpnpInitThreadPools(void)
{
	int ret = UPNP_E_SUCCESS;
	ThreadPoolAttr attr;

	TPAttrInit(&attr); // 初始化属性,然后设置线程池的最大最小线程数,每个线程的JOB数量等等
	TPAttrSetMaxThreads(&attr, MAX_THREADS);
	TPAttrSetMinThreads(&attr, MIN_THREADS);
	TPAttrSetStackSize(&attr, THREAD_STACK_SIZE);
	TPAttrSetJobsPerThread(&attr, JOBS_PER_THREAD);
	TPAttrSetIdleTime(&attr, THREAD_IDLE_TIME);
	TPAttrSetMaxJobsTotal(&attr, MAX_JOBS_TOTAL);

	// 然后利用以上属性初始化三个全局线程池
	if (ThreadPoolInit(&gSendThreadPool, &attr) != UPNP_E_SUCCESS) {
		ret = UPNP_E_INIT_FAILED;
		goto exit_function;
	}

	if (ThreadPoolInit(&gRecvThreadPool, &attr) != UPNP_E_SUCCESS) {
		ret = UPNP_E_INIT_FAILED;
		goto exit_function;
	}

	if (ThreadPoolInit(&gMiniServerThreadPool, &attr) != UPNP_E_SUCCESS) {
		ret = UPNP_E_INIT_FAILED;
		goto exit_function;
	}

exit_function:
	if (ret != UPNP_E_SUCCESS) {
		UpnpSdkInit = 0;
		UpnpFinish();
	}

	return ret;
}

函数ThreadPoolInit初始化并启动线程池

函数声明

// https://github1s.com/pupnp/pupnp/blob/branch-1.14.x/upnp/src/threadutil/ThreadPool.h#L252-L280
/*!
 * \brief 初始化并启动线程池。必须首先调用此函数,并且只能调用一次以初始化线程池。
 *
 * \return
 * \li \c 0 表示成功。
 * \li \c EAGAIN 表示系统资源不足,无法创建最小数量的线程。
 * \li \c INVALID_POLICY 表示无法设置调度策略。
 * \li \c EMAXTHREADS 表示最小线程数大于最大线程数。
 */
int ThreadPoolInit(
	/*! 必须是有效的、非空的 ThreadPool 指针。 */
	ThreadPool *tp,
	/*! 可以为 NULL。如果不为 NULL,则 attr 包含以下字段:
	 * \li \c minWorkerThreads - 线程池中最少的工作线程数量,线程池不会少于这个数量的线程。
	 * \li \c maxWorkerThreads - 线程池中最多的工作线程数量,线程池不会超过这个数量的线程。
	 * \li \c maxIdleTime - 工作线程保持空闲的最长时间。如果线程空闲时间超过此值且
	 * 运行中的线程数超过最小数量,则该工作线程退出。
	 * \li \c jobsPerThread - 每个线程要维护的任务与线程的比率。如果调度任务时每个线程的任务
	 * 数超过这个比率,并且运行中的工作线程数少于最大线程数,则启动一个新线程以提高效率。
	 * \li \c schedPolicy - 尝试设置的调度策略(依赖于操作系统)。
	 */
	ThreadPoolAttr *attr);

函数定义

  • 先进行线程池加锁,然后初始化线程池tp,后续解锁。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值