加入收藏 | 设为首页 | 会员中心 | 我要投稿 成都站长网 (https://www.028zz.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

linux下的线程池编写:疑似唤醒丢失的无限等待

发布时间:2022-10-14 13:31:34 所属栏目:Linux 来源:互联网
导读: 前一段时间看到网上一位大神的线程池代码很不错,就仿照其功能自己写了一个,结果出现的问题是,只能对一个线程的条件变量解除阻止线程池linux,其余的线程都会停止在pthread_join函数,无

前一段时间看到网上一位大神的线程池代码很不错,就仿照其功能自己写了一个,结果出现的问题是,只能对一个线程的条件变量解除阻止线程池linux,其余的线程都会停止在pthread_join函数,无限等待,本以为是pthread_cond_broadcast唤醒丢失,后来发现不是这个原因,先卖个关子,大家看看什么问题

#include

#include

#include

#include

void * threadprocess(void *arg);

typedef struct worker

{

void (*process)(void *arg);

void *arg;

struct worker *next;

}worker;

typedef struct pool

{

worker *head;

worker *end;

int maxthread;

bool shutdown;

int cur_size;

pthread_t * pid;

pthread_mutex_t pm;

pthread_cond_t pc;

}pool;

pool *t_pool=NULL;

void pool_init(char *argv[])

{

int maxsize=atoi(argv[1]);

t_pool=(pool *)malloc(sizeof(pool));

t_pool->pid=(pthread_t *)malloc(sizeof(pthread_t)*maxsize);

t_pool->maxthread=maxsize;

t_pool->head=NULL;

t_pool->end=NULL;

t_pool->cur_size=0;

pthread_mutex_init(&t_pool->pm,NULL);

pthread_cond_init(&t_pool->pc,NULL);

t_pool->shutdown=0;

for(int i=0;i {

pthread_create(&(t_pool->pid[i]),NULL,threadprocess,NULL);

}

}

void * threadprocess(void *arg)

{

worker *p=NULL;

while(t_pool->shutdown==0)

{

pthread_mutex_lock(&t_pool->pm);

while(t_pool->head==NULL&&t_pool->shutdown==0)

{

printf("process %d is waiting\n",pthread_self());

pthread_cond_wait(&t_pool->pc,&t_pool->pm);

printf("There is no task we could do\n");

}

if(t_pool->shutdown==1)

{

printf("\n\nprocess %d over\n\n",pthread_self());

pthread_exit(NULL);

}

printf("\n this is the %d process\n",pthread_self());

if(t_pool->head!=NULL)

{

p=t_pool->head;

t_pool->head=t_pool->head->next;

(*p->process)(p->arg);

free(p);

t_pool->cur_size--;

}

pthread_mutex_unlock(&t_pool->pm);

}

}

void thread_destroy(char *argv[])

{

t_pool->shutdown=1;

pthread_mutex_lock(&t_pool->pm);

pthread_cond_broadcast(&(t_pool->pc));

pthread_mutex_unlock(&t_pool->pm);

int i=atoi(argv[1]);

for(int j=0;j {

pthread_join(t_pool->pid[j],NULL);

}

while(t_pool->head!=NULL)

{

worker *wk=t_pool->head;

t_pool->head=t_pool->head->next;

free(wk);

}

t_pool->cur_size=0;

t_pool->head=NULL;

t_pool->end=NULL;

free(t_pool->pid);

t_pool->pid=NULL;

pthread_mutex_destroy(&t_pool->pm);

pthread_cond_destroy(&t_pool->pc);

t_pool=NULL;

}

int main(int argc,char *argv[])

{

printf("\n\n--------------------------------------------------------------------\n");

pool_init(argv);

sleep(2);

thread_destroy(argv);

printf("\n\nThe number of thread is %s\n",argv[1]);

return 0;

}

有没有什么想法?

原因很简单,还是跟互斥锁有关系,由于在pthread_cond_wait收到条件变量的释放信号后还要进行上锁,所以,这就要等到pthread_cond_broadcast下面一行的pthread_mutex_unlock解锁,然后pthread_cond_wait对其上锁完毕后pthread_cond_wait才能完全返回,这时的互斥锁是在上锁状态,然后由于我调用了pthread_exit造成了线程退出,而互斥锁没有解锁,其余的线程在pthread_cond_wait处无法获得互斥锁返回,于是就一直阻塞在pthread_cond_wait处,而我又调用了pthread_join函数对线程进行等待,所以,线程就进入了无限等待状态。

一直以为是唤醒丢失,但不是唤醒丢失

再说一下唤醒丢失吧

唤醒丢失原因很简单,一般来说就是在线程还没有进入等待状态的时候,你就调用了唤醒函数(pthread_cond_signal或者pthread_cond_broadcast),那么线程自然无法接收到唤醒信号,这时的唤醒信号无效,但是程序也不会返回错误。

参考:

才疏学浅,如果有不对的地方,大神们多多指正

(编辑:成都站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!