代码拉取完成,页面将自动刷新
#include<iostream>
#include<thread>
#include<mutex>
#include<ctime>
#include <semaphore.h>
#include <string.h>
#define MAX 10
#define MAX_ACTIVE_THREADS 10
#define MAX_WAITING_TASKS 5
bool choosing[MAX] = {0};
int number[MAX] = {0};
void *routine(void *arg);
struct task
{
void *(*task)(void *arg); //指针函数(即这个任务要去做什么事情)
void *arg; //参数
struct task *next; //指向下一个任务的指针
};
typedef struct thread_pool
{
pthread_mutex_t lock;//互斥锁
pthread_cond_t cond;//条件变量
struct task *task_list;//任务链表
pthread_t *tids; //存储创建线程id号
unsigned waiting_tasks; //任务队列中正在等待的任务个数
unsigned active_threads; //正在工作的线程个数
bool shutdown; //开关标志
}thread_pool;
typedef struct
{
void *pool_arg;
//thread_pool *pool_arg;
int id;
}param;
bool pool_init(thread_pool *pool,unsigned int threads_num)//初始化线程池
{
int i;
pthread_mutex_init(&pool->lock,NULL);
pthread_cond_init(&pool->cond,NULL);
pool->task_list=(task*)malloc(sizeof(struct task)); //初始化任务链表
memset(pool->task_list, 0, sizeof(struct task));
pool->waiting_tasks=0;
pool->active_threads=threads_num;
pool->shutdown=false;
pool->tids=(pthread_t*)malloc(sizeof(pthread_t)*MAX_ACTIVE_THREADS); //MAX_ACTIVE_THREADS为一个宏,表示要能容纳的最大线程数
memset(pool->tids, 0, sizeof(pthread_t)*MAX_ACTIVE_THREADS);
if(pool->task_list==NULL||pool->tids==NULL)
{
perror("allocate memory error");
return false;
}
pool->task_list->next=NULL;
for(i=0;i<pool->active_threads;i++)
{
param par;
par.id = i;
par.pool_arg =NULL;
//par.pool_arg = (void *)pool;
printf("yuanlai pool_arg:%d\n", par.pool_arg);
printf("yuanlai i:%d\n", par.id);
//printf("size i:%d\n", sizeof(par));
if(pthread_create(&((pool->tids)[i]),NULL,routine,(void*)&par)!=0)
{
perror("create thread failed!\n");
return false;
}
}
return true;
}
bool add_task(thread_pool *pool,void *(*task_newadd)(void *arg),void *arg)
{
struct task *new_task=(task*)malloc(sizeof(struct task));
if(new_task==NULL)
{
perror("allocate memory error");
return false;
}
new_task->task=task_newadd;//任务存入新节点
new_task->arg=arg;
new_task->next=NULL;
pthread_mutex_lock(&pool->lock);
if(pool->waiting_tasks>=MAX_WAITING_TASKS)
{
pthread_mutex_unlock(&pool->lock);
fprintf(stderr,"too many tasks.\n");//任务太多添加失败
free(new_task);
return false;
}
//遍历链表,找到队列尾结点,以便把新结点加入
struct task *tmp=pool->task_list;
while(tmp->next!=NULL) tmp=tmp->next;
tmp->next=new_task;
pool->waiting_tasks++;
pthread_mutex_unlock(&pool->lock); //解互斥锁
pthread_cond_signal(&pool->cond); //解锁后唤醒一个阻塞在条件变量的线程,因为线程被创建后执行的函数都会默认被阻塞
return true;
}
bool destroy_pool(thread_pool *pool)
{
pool->shutdown = true;
pthread_cond_broadcast(&pool->cond); //唤醒因条件变量沉睡的所有线程
int i;
for(i=0;i<pool->active_threads;i++)
{
errno=pthread_join(pool->tids[i],NULL); //等待线程回收完毕
if(errno!=0)
{
printf("join tids[%d] error:%s\n",i,strerror(errno));
}
else
printf("[%u] is joined\n",(unsigned)pool->tids[i]);
}
free(pool->task_list);
free(pool->tids);
free(pool);
return true;
}
int max(int a[MAX]){
int max = a[0]; // 我们假定第一个数是最大的数
int i; // 让数组中其他数和我们假定的最大的数比较
for (i = 1; i < MAX; i++) // 对数组中的数遍历
{
if (a[i] > max) // 让它们依次比较,如果比我们假定的数大
max = a[i]; // 我们就将那个较大的数的值给max
}
return max;
}
void *routine(void *arg)
{
param* para = (param*)arg;
int i = para->id;
//thread_pool *pool ;//= (thread_pool*)(*para).pool_arg;
thread_pool *pool = (thread_pool*)(*para).pool_arg;
printf("pool_arg:%d\n", (*para).pool_arg);
printf("i:%d\n",i);
struct task *p;
if(i<0 || i>11) pthread_exit(NULL);//退出;
printf("200\n");
pthread_exit(NULL);
while(1)
{
pthread_mutex_lock(&pool->lock);
printf("204\n");
//判断任务链表中是否有节点,没有就阻塞当前线程
while(pool->waiting_tasks == 0 && !pool->shutdown) //这个循环的作用是,当没任务时让线程沉睡,有任务时循环取任务
{
pthread_cond_wait(&pool->cond,&pool->lock); //让线程沉睡
}
if(pool->waiting_tasks==0&&pool->shutdown==true) //shutdown=true也要等任务全执行完了才能删除线程池
{
pthread_mutex_unlock(&pool->lock);
pthread_exit(NULL);
}
printf("215\n");
choosing[i] = true;// number 为上一个已发放的排队号加 1
number[i] = 1 + max(number);// 当前进程 i 取号完毕
choosing[i] = false;// 迭代所有进程
for (int j = 0; j < MAX; j++){// 若当前迭代到的进程 j 正在取号,则等待其取号完毕
while(choosing[j]) pthread_cond_wait(&pool->cond,&pool->lock);// 同时满足,当前进程才能通过
while (number[j] != 0 && (number[j], j) < (number[i], i)) pthread_cond_wait(&pool->cond,&pool->lock);//(a, b) < (c, d) 表示 (a < c) or ((a == c) and (b < d))
}
p =pool->task_list->next;
pool->task_list->next =p->next;
pool->waiting_tasks--;
//解锁
pthread_mutex_unlock(&pool->lock);
(p->task)(p->arg); //执行任务
//释放定义的那个节点
number[i] = 0;
free(p);
}
pthread_exit(NULL);//退出
}
// void process(int i) {
// while (true) {// 当前进程 i 正在取号
// choosing[i] = true;// number 为上一个已发放的排队号加 1
// number[i] = 1 + max(number);// 当前进程 i 取号完毕
// choosing[i] = false;// 迭代所有进程
// for (int j = 0; j < MAX; j++){// 若当前迭代到的进程 j 正在取号,则等待其取号完毕
// while(choosing[j]);// 同时满足,当前进程才能通过
// while (number[j] != 0 && (number[j], j) < (number[i], i));//(a, b) < (c, d) 表示 (a < c) or ((a == c) and (b < d))
// }
// // 临界区代码
// // 当前进程注销排队号
// // 一旦线程在临界区执行完毕,需要把自己的排队签到号码置为 0,表示处于非临界区
// number[i] = 0;
// // 其它代码
// }
// }
void *eatapple(void *arg){
printf("eat apple\n");
}
int main(){
thread_pool *pool;
pool=(thread_pool*)malloc(sizeof(struct thread_pool));
memset(pool, 0, sizeof(struct thread_pool));
pool_init(pool,1);
add_task(pool,eatapple,NULL);
add_task(pool,eatapple,NULL);
destroy_pool(pool);
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。