根据Linux 线程挂起与唤醒原理,实现Sleep的暂停与继续

来源:互联网 发布:小葫芦数据检测作假 编辑:程序博客网 时间:2024/04/25 21:57


int pthread_cond_wait( pthread_cond_t  *cond,pthread_mutex_t  *mutex );

多线程的条件变量

条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线程使"条件成立"(给出条件成立信号)。为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起。


创建和注销

条件变量和互斥锁一样,都有静态动态两种创建方式

      静态方式使用PTHREAD_COND_INITIALIZER常量,如下:

pthread_cond_t  cond = PTHREAD_COND_INITIALIZER;
动态方式调用pthread_cond_init()函数,API定义如下:
int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);
尽管POSIX标准中为条件变量定义了属性,但在LinuxThreads中没有实现,因此cond_attr值通常为NULL,且被忽略。

等待和激发

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)

在调用pthread_cond_wait()前必须由本线程加锁(pthread_mutex_lock(),而在更新条件等待队列以前,mutex保持锁定状态,并在线程挂起进入等待前解锁。在条件满足从而离开pthread_cond_wait()之前,mutex将被重新加锁,以与进入pthread_cond_wait()前的加锁动作对应。

int pthread_cond_signal(pthread_cond_t  *cond);

       pthread_cond_signal() 函数唤醒一个等待该条件的线程,存在多个等待线程时按入队顺序唤醒其中一个。

int pthread_cond_broadcast(pthread_cond_t  *cond);

       pthread_cond_broadcast() 函数唤醒等待该条件的所有线程。

打个比方对比一下二者的区别

pthread_cond_signal()与pthread_cond_broadcast()均为通知一个等待,

但是pthread_cond_broadcast会打断所有的等待,比如东西10人,南北10人过马路,南北的绿灯亮了,南北、东西行人均通知了,南北行人走,东西行人不走;

pthread_cond_signal() 只会打断等待的人当中的一个,比如警察带领10个盲人过马路,每次只能领一个。


伪码大概如下


#include <stdio.h> 

#include <string.h> 

#include <pthread.h>

static  int  sleep_value;

static  pthread_mutex_t  mutex = PTHREAD_MUTEX_INITIALIZER;

static  pthread_cond_t  cond = PTHREAD_COND_INITIALIZER;

void  sleep_function( int sleep_time )

{

    static int cur_sleep_time = 0;

    while(1)

    {

        pthread_mutex_lock(&mutex);

        while(sleep_value)

                pthread_cond_wait(&cond,&mutex);

        pthread_mutex_unlock(&mutex);

        sleep(1);

        cur_sleep_time++;

        if(cur_sleep_time == sleep_time)

            break;

    }   

}

void sleep_stop(void)

{

    pthread_mutex_lock(&mutex);

    sleep_value++;

    pthread_mutex_unlock(&mutex);

}

void sleep_resume(void)

{

    pthread_mutex_lock(&mutex);

    if(sleep_value)

    {

       sleep_value--;

        if(sleep_value == 0)

            pthread_cond_signal(&cond);

    }

    pthread_mutex_unlock(&unlock);

}


注:sleep_funtion()是自己封装的sleep函数,其实现原理是将sleep(time)分解为sleep(1)来实现

sleep_stop()主要使sleep_value的值自增来实现sleep的暂停,与sleep_function()结合来看,当sleep_value不为0时,便会通过pthread_cond_wait()实现等待,从而实现暂停计时。

sleep_resume()主要使sleep_value的值自减,每次自减判断一下sleep_value是否为0,当sleep_value=0时,便会通pthread_cond_signal()打断pthread_cond_wait(),从而实现继续计时。


1 0