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

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

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>


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<atoi(argv[1]);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<i;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),那么线程自然无法接收到唤醒信号,这时的唤醒信号无效,但是程序也不会返回错误。

参考:http://blog.csdn.net/ithomer/article/details/6031723

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值