互斥量

互斥量(互斥锁)

(1) 互斥锁类型: pthread_mutex_t, 定义一个变量相当于创建一把锁

(2) 互斥锁的特点
  多个线程传行访问共享数据

(3) 使用互斥锁缺点
  效率低

(4) 互斥锁的使用步骤

  创建互斥锁: pthread_mutex_t mutex
  初始化: pthread_mutex_init(&mutex, NULL)
  加锁
    pthread_mutex_lock(&mutex) 阻塞线程
    pthread_mutex_trylock(&mutex) 如果上锁, 直接返回, 不阻塞, 需要对返回值进行判断
  共享数据操作----> 临界区
  解锁: pthread_mutex_unlock(&mutex), 阻塞在锁上的线程会被唤醒
  销毁锁:pthread_mutex_destroy(&mutex)

(5) 互斥锁相关函数
  初始化互斥锁: 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);

if (pthread_mutex_trylock(&mutex) == 0) {
	// 尝试加锁, 并且成功
	// 访问共享资源
}
else {
	// 错误处理
	// 或者等一会, 再次尝试加锁
}

    没有被锁上: 当前线程会给这把锁加锁
    锁上: 不会阻塞, 返回
  解锁int pthread_mutex_unlock(pthread_mutex_t *mutex);

加锁

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <pthread.h>

#define MAX 100

// 全局变量
int number;

// 创建一把互斥锁
pthread_mutex_t mutex;

void *myfuncA(void *arg) {
    int i;
    for (i = 0; i < MAX; i++) {
        pthread_mutex_lock(&mutex);     // 加锁
        int cur = number;
        cur++;
        number = cur;
        printf("Thread_A, id = %ld, number = %d\n", pthread_self(), number);
        pthread_mutex_unlock(&mutex);   // 解锁
        usleep(10);                     // 为使线程A放弃cpu, 加sleep
    }

    return NULL;
}

void *myfuncB(void *arg) {
    int i;
    for (i = 0; i < MAX; i++) {
        pthread_mutex_lock(&mutex);     // 加锁
        int cur = number;
        cur++;
        number = cur;
        printf("Thread_B, id = %ld, number = %d\n", pthread_self(), number);
        pthread_mutex_unlock(&mutex);   // 解锁
        usleep(10);                     // 为使线程B放弃cpu, 加sleep
    }

    return NULL;
}

int main(void) {
    pthread_t p1, p2;

    // 初始化互斥锁
    pthread_mutex_init(&mutex, NULL);

    // 创建线程
    pthread_create(&p1, NULL, myfuncA, NULL);
    pthread_create(&p2, NULL, myfuncB, NULL);

    // 回收
    pthread_join(p1, NULL);
    pthread_join(p2, NULL);

    // 销毁锁
    pthread_mutex_destroy(&mutex);
    return 0;
}

哲学家吃饭

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <pthread.h>

pthread_mutex_t mutex[5];

void *dinner(void *arg) {
    int num = (int)arg;
    int left, right;

    if (num < 4) {
        // 前4个人, 右手拿自己的筷子
        right = num;
        left = num + 1;
    }
    else if (num == 4) {
        // 最后一个人, 右手拿别人筷子
        right = 0;
        left = num;
    }

    // 吃饭
    while (1) {
        // 右手加锁
        pthread_mutex_lock(&mutex[right]);
        // 尝试抢左手筷子
        if (pthread_mutex_trylock(&mutex[left]) == 0) {
            // 吃面
            printf("%c正在吃面......\n", num+'A');
            // 吃完放下筷子
            pthread_mutex_unlock(&mutex[left]);
        }
        // 右手解锁
        pthread_mutex_unlock(&mutex[right]);
        sleep(rand() % 5);
    }
    return NULL;
}

int main(void) {
    int i;
    pthread_t p[5];
    for (i = 0; i < 5; i ++)
        pthread_mutex_init(&mutex[i], NULL);
    
    for (i = 0; i < 5; i ++)
        pthread_create(&p[i], NULL, dinner, (void *)i);

    for (i = 0; i < 5; i ++)
        pthread_join(p[i], NULL);
    for (i = 0; i < 5; i ++)
        pthread_mutex_destroy(&mutex[i]);

    return 0;
}
posted @ 2019-04-19 21:38  张飘扬  阅读(316)  评论(0编辑  收藏  举报