日期:2014-05-16  浏览次数:20643 次

linux下怎么实现等待一个标志位为1前,一直睡眠(阻塞)
例如程序中有一个标志位is_done,有没有特定的函数能实现,is_done 等于0时一直阻塞,等待为1时,函数才继续向下进行。

------解决方案--------------------
mutex + cond 挂起等待唤醒。


SYNOPSIS
#include <pthread.h>

int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_signal(pthread_cond_t *cond);
SYNOPSIS
#include <pthread.h>

int pthread_cond_timedwait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex,
const struct timespec *restrict abstime);
int pthread_cond_wait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex);

SYNOPSIS
#include <pthread.h>

int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);



SYNOPSIS
#include <pthread.h>

int pthread_mutex_destroy(pthread_mutex_t *mutex);
int pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
SYNOPSIS
#include <pthread.h>

int pthread_cond_destroy(pthread_cond_t *cond);
int pthread_cond_init(pthread_cond_t *restrict cond,
const pthread_condattr_t *restrict attr);
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

以上是你需要了解的函数。
------解决方案--------------------
也可以配合select实现, 你这个应该是多线程吧
is_done应该说是<= int型, 读取和赋值是原子的。 所以可以不用锁。 但最好得申明为volatile

volatile int is_done = 0;
int fd[2] = { -1 , -1}; //fd[0]接受通知, fd[1]发送通知,,这个得处于全局位置。这种方式可以通知很多情况
if(pipe(fd) == -1) { //在最开始就初始化。
perror("pipe error");
}

void wait_done_flag(void)
{
fd_set rset;
while(!is_done) {
FD_ZERO(&rset);
FD_SET(fd[0], &rset);
if(select(fd[0] + 1 , &rset , NULL , NULL , NULL) == -1) {
if(errno != EAGAIN && errno != EINTR){
perror("select error");
break;
}
}
}
}

然后别的线程改变is_done变量后,就使用write(fd[1] , "" , 1); 写入一个字节。这个可以封装成函数
void set_done_flag(void)
{
is_done = 1;
write(fd[1] , "" , 1);
}