前一段时间看到网上一位大神的线程池代码很不错,就仿照其功能自己写了一个,结果出现的问题是,只能对一个线程的条件变量解除阻止,其余的线程都会停止在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
才疏学浅,如果有不对的地方,大神们多多指正