【11】Strongswan processor 详解1

processor_t结构体,声明了一些公用方法:

get_total_threads获取总的线程数量;

get_idle_threads获取空闲线程数量;

get_working_threads按指定的优先级获取处理该优先级的job的线程数量;

get_job_load 或取指定优先级job队列中的job数量;

queue_job 添加job到指定job优先级对应的队列中;

execute_job直接调用一个空闲线程处理job,如果没有空闲线程则直接由调用该接口的线程直接处理job。

set_threads 设置线程池中的线程数量,这可能导致线程池的扩大或缩小。

cancel 线程数量设置为0,取消线程池,直到所有job处理完毕。

destroy 销毁processor对象。

private_processor_t 结构体继承processor_t结构体,

processor_create函数创建一个processor_t对象,其中挂载公有函数初始化processor_t对象,除此之外,private_processor_t还有私有的成员:

total_threads 正在运行的工作线程数量,他们可能处于等待job_added条件变量中或正在处理job;

desired_threads 用户指定的线程数量;set_threads 设置的线程数量会保存。

working_threads数组,每个优先级的线程数量;

threads 链表,保存线程池中所有的线程;

jobs数组,每个优先级的job链表;

prio_threads数组,每个优先级指定的线程数量;

mutex互斥锁

job_added条件变量,加入job通知,线程从条件变量处继续执行,从队列中取job执行。

thread_terminated 线程结束条件变量。线程函数退出时发送该信号,上述cancel函数接收该信号。

worker_thread_t结构体描述一个工作线程:

processor 指向实例化的processor对象;

thread 指向工作线程;

job 指向将要被该线程处理的job;

priority job的优先级。

get_idle_threads_nolock函数:

total_threads 总的线程数减去正在执行job的线程数量。

get_job函数:

值越小,优先级越高,从最高优先级的job开始,避让算法,prio_threads[i]大于working_threads[i]说明该i级别的job处理线程不够,reserved保存缺口数量,在for循环执行到下一个优先级的job时,reserved >= idle的化就直接退出不处理,优先高级别的job。跳过这些能get了,就remove_first从该优先级的job链表中取出第一个job。

process_jobs函数:

是线程池多有线程的执行函数。

while (this->desired_threads >= this->total_threads)决定是否跳出循环结束线程,当不成立时说明desired_threads 变小了,线程池缩小了,要把执行完job的线程退出。否则则取出worker线程优先级一致的job,调用process_job处理job,注意互斥锁的加锁与解锁,入时解锁处理job,出时加锁继续下一次的保护。没有job则条件等待。由于条件等待不超时,所以线程池的缩放需要加入job的信号激活。

那么当此线程退出时,发生了线程池缩小,total_threads线程数减少,发送thread_terminated条件信号。在cancel函数中接收判断线程是否都已经释放了:

c 复制代码
	while (this->total_threads > 0)
	{
		this->job_added->broadcast(this->job_added);
		this->thread_terminated->wait(this->thread_terminated, this->mutex);
	}

process_job函数处理job:

(1) working_threads++ 增加总的在处理job数

(2) 由于thread_cleanup_pop(FALSE);纯如false,不必理会

(3)调用job->execute的处理job,返回值的几种类型:

若是JOB_REQUEUE_TYPE_NONE,则!= JOB_REQUEUE_TYPE_DIRECT,跳出循环,后续to_destroy = worker->job; 进而to_destroy->destroy(to_destroy);销毁job。

若是JOB_REQUEUE_TYPE_DIRECT,则是再直接执行job->execute,前提是worker->job->cancel不为空,也即可取消,否则while中一直执行不可取消了。

若是JOB_REQUEUE_TYPE_FAIR,后续插入job队列。

若是JOB_REQUEUE_TYPE_SCHEDULE,则...

JOB_REQUEUE_TYPE_DIRECT:

(4)调用job->execute后,working_threads--

(5)如果在job->execute时,worker->job->status 设置为 JOB_STATUS_CANCELED,则销毁job。

queue_job函数:

按不同的优先级插入job,并向线程发送条件变量信号激发处理。

execute_job:

如果有空闲线程,插入和job相同优先级的队列的首部,唤醒等待此条件变量的线程,

如果插入队列没有成功,则由调用此函数的线程直接处理job的execute函数

set_threads:

(1)根据配置预设各优先级job的处理线程数量。

(2)根据要设置的count线程数,扩充或缩小线程池。

(3)缩小,则this->desired_threads = count;,在process_jobs函数中,处理完job后会while条件判断失败,退出循环,退出该线程,达到减少目的。

(4)扩大,则thread_create创建新的线程。

线程局部存储变量private_thread_t :

c 复制代码
//每个线程的id、cleanup_handlers之类在不同的存储空间,互不影响。
thread_t *thread_current()
{
	private_thread_t *this;

	this = (private_thread_t*)current_thread->get(current_thread);
	if (!this)
	{
		this = thread_create_internal();
		this->id = get_thread_id();
		current_thread->set(current_thread, (void*)this);
	}
	return &this->public;
}

u_int thread_current_id()
{
	private_thread_t *this = (private_thread_t*)thread_current();

	return this ? this->id : 0;
}

void thread_cleanup_push(thread_cleanup_t cleanup, void *arg)
{
	private_thread_t *this = (private_thread_t*)thread_current();
	cleanup_handler_t *handler;

	INIT(handler,
		.cleanup = cleanup,
		.arg = arg,
	);

	this->cleanup_handlers->insert_last(this->cleanup_handlers, handler);
}

(1)在多线程编程中,pthread_setspecific 和 pthread_getspecific 是两个用于处理线程局部存储(TLS)的函数,

(2)它们允许线程存储和访问线程特定的数据。这些函数提供了一种在同一线程中不同函数间共享数据的方法,这对于创建线程安全的程序至关重要。

(3)线程局部存储是一种允许数据在多个线程间独立存在的机制。每个线程都有自己的数据副本,因此对这些数据的操作不会影响其他线程。

(4)这种机制在处理不支持原子操作的自定义数据类型时尤其有用,因为它可以在不使用锁的情况下实现线程安全。

(5)要使用这些函数,首先需要通过 pthread_key_create 创建一个 pthread_key_t 类型的键。这个键用于标识线程特定的数据。

(6)然后,可以使用 pthread_setspecific 将数据与键关联,使用 pthread_getspecific 获取与键关联的数据。

(7)在上述代码中,pthread_setspecific 用于设置线程特定的数据,而 pthread_getspecific 用于获取这些数据。

(8)每个线程都有自己的数据副本,因此即使是使用相同的键,不同线程中的数据也是独立的。

相关推荐
独行soc5 小时前
#渗透测试#批量漏洞挖掘#HSC Mailinspector 任意文件读取漏洞(CVE-2024-34470)
linux·科技·安全·网络安全·面试·渗透测试
Me4神秘6 小时前
电信、移动、联通、广电跨运营商网速慢原因
网络
Whoisshutiao7 小时前
网安-XSS-pikachu
前端·安全·网络安全
数通Dinner7 小时前
RSTP 拓扑收敛机制
网络·网络协议·tcp/ip·算法·信息与通信
liulilittle8 小时前
SNIProxy 轻量级匿名CDN代理架构与实现
开发语言·网络·c++·网关·架构·cdn·通信
tan77º9 小时前
【Linux网络编程】Socket - UDP
linux·服务器·网络·c++·udp
小白爱电脑9 小时前
光纤的最小弯曲半径是多少?
网络
花落已飘11 小时前
多线程 vs 异步
linux·网络·系统架构
qq_1715388513 小时前
TCP/IP协议精解:IP协议——互联网世界的邮政编码系统
网络·网络协议·tcp/ip
珹洺14 小时前
计算机网络:(七)网络层(上)网络层中重要的概念与网际协议 IP
网络·tcp/ip·计算机网络