UNIX 互斥锁和条件变量的使用例程

使用条件变量和互斥锁实现线程同步
条件变量(cond)使在多线程程序中用来实现“等待--->唤醒”逻辑常用的方法,是进程间同步的一种机制。条件变量用来阻塞一个线程,直到条件满足被触发为止,通常情况下条件变量和互斥量同时使用。一般条件变量有两个状态:(1)一个/多个线程为等待“条件变量的条件成立“而挂起;(2)另一个线程在“条件变量条件成立时”通知其他线程。

互斥锁的作用: 
1. 保护共享数据。 再并发机制的情况下,有时候会有多个线程同时访问同一片数据,为了保护数据操作的原子性就使用互斥锁来保证数据操作的准确性。
2. 保持操作的互斥性。可能一个程序会有多个操作,但是同一个时间只能有一个操作被执行。

为什么条件变量总是和互斥锁结合使用?
1. 互斥锁可以表示的状态太少,所以经常需要条件变量来增加有限的状态
2. 条件变量只是条件,还需要互斥量的保护, 线程改变条件状态之前先要锁住互斥量。
3. 线程之间交换互斥锁的控制权,会带来不必要的时间消耗,加上条件变量就弥补这个弱点


互斥锁的基本函数:
#include <pthread.h>

// 创建一个互斥锁
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr); 

// 销毁一个互斥锁
int pthread_mutex_destroy(pthread_mutex_t *mutex);

// 给一个互斥锁上锁
int pthread_mutex_lock(pthread_mutex_t *mutex);

// 给一个互斥锁上锁但是不会阻塞
int pthread_mutex_trylock(pthread_mutex_t *mutex);

// 给一个互斥锁开锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);


条件变量的基本函数:
#include <pthread.h>

// 初始化一个条件变量
int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);

// 销毁一个条件变量
int pthread_cond_destroy(pthread_cond_t *cond);

// 等待一个条件变量 
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);

// 带时间限制的条件变量
int pthread_cond_timedwait(pthread_cond_t *restrict cond,  pthread_mutex_t *restrict mutex, 
const struct timespec *restrict abstime);


条件变量和互斥锁的变量类型定义:   pthread_mutex_t和pthread_cond_t类型
typedef union                                   typedef union
{                                               {
  struct __pthread_mutex_s __data;                  struct __pthread_cond_s __data;
  char __size[__SIZEOF_PTHREAD_MUTEX_T];            char __size[__SIZEOF_PTHREAD_COND_T];  
  long int __align;                                 __extension__ long long int __align;
} pthread_mutex_t;                              } pthread_cond_t;
 

#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <time.h>
#include <string.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/wait.h>
#include <semaphore.h>
#include <pthread.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <time.h>
#include <pthread.h>
#include "my_print.h"

#define MAXLINE 4096
#define err_quit(s) (perror(s), exit(EXIT_FAILURE))

int x = 0;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

void *wait_ture(void *argv);
void *do_ture(void *argv);

int main(int argc, char **argv)
{
    pthread_t threadid[2];

    // 创建互斥锁和条件变量
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);

    pthread_create(&threadid[0], NULL, wait_ture, NULL);
    sleep(2);
    pthread_create(&threadid[1], NULL, do_ture, NULL);

    pthread_join(threadid[0], NULL);
    pthread_join(threadid[1], NULL);

    pthread_cond_destroy(&cond);

    return 0;
}

void *wait_ture(void *argv)
{
    int ret;

    // 上锁,别的线程会被阻塞,执行到等待条件变量的时候线程被挂起,这个互斥锁就会被解锁了
    printr("befor mutex\n");
    ret = pthread_mutex_lock(&mutex);
    printr("after mutex\n");

    if (ret < 0)
        err_quit("lock error");

    // 线程挂起,互斥锁会被解锁
    if (pthread_cond_wait(&cond, &mutex) == 0)
        printr("wait success! x = %d.\n", x);

    pthread_mutex_unlock(&mutex);

    return NULL;
}

void *do_ture(void *argv)
{
    int ret;

    // 获取互斥锁,前面函数等待这里的条件变量就会挂起,这里就会获得互斥锁
    ret = pthread_mutex_lock(&mutex);

    while (x != 4)
    {
        if (ret < 0)
            err_quit("mutex error");
        else if (ret == 0)
        {
            x++;
            printf("done for true, x = %d\n", x);
            sleep(1);
        }
    }
    pthread_mutex_unlock(&mutex);

    ret = pthread_cond_signal(&cond);
    if (ret != 0)
        printf("unlock mutex error");

    return NULL;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值