互斥锁和读写锁操作

本文详细介绍了互斥锁、读写锁和条件变量在C++中的使用方法,包括初始化、销毁以及各自的锁定、解锁操作,以及条件变量如何配合互斥锁实现线程同步。
摘要由CSDN通过智能技术生成

互斥锁

1.互斥锁初始化

#include <pthread.h>

函数原型:

       int  pthread_mutex_init(pthread_mutex_t  *mutex,  const  pthread_mutex‐

       attr_t *mutexattr);

参数:

       pthread_mutex_t  *mutex,   互斥锁对象,申请对象

const  pthread_mutexattr_t *mutexattr 属性较多,一般设置为NULL

2.互斥锁的销毁

#include <pthread.h>

函数原型:

       int pthread_mutex_destroy(pthread_mutex_t *mutex);

参数:

       pthread_mutex_t *mutex  互斥锁对象

3.互斥锁的操作

#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); // 解锁

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>

// 定义互斥锁变量
pthread_mutex_t mutex;

// 子线程
void *func(void *arg)
{
	// 上锁保护共享资源,抢到就上锁,抢不到就阻塞
	pthread_mutex_lock(&mutex);
	/*任务*/
	char *str = "hello";
	for(int i=0; i<strlen(str); i++)
	{
		printf("%s:%c\n", (char *)arg, str[i]);
		sleep(1);
	}
	// 解锁
	pthread_mutex_unlock(&mutex);
	// 子线程退出
	pthread_exit(NULL);
}

int main(int argc, char const *argv[])
{
	// 初始化互斥锁
	pthread_mutex_init(&mutex, NULL);
	// 定义线程号
	pthread_t tid1, tid2;
	// 创建线程
	pthread_create(&tid1, NULL, func, (void *)"线程1");
	pthread_create(&tid2, NULL, func, (void *)"线程2");

	// 回收子线程
	pthread_join(tid1, NULL);
	pthread_join(tid2, NULL);
	
	// 销毁互斥锁
	pthread_mutex_destroy(&mutex);

	return 0;
}

 读写锁

1.初始化读写锁

       #include <pthread.h>

函数原型:

       int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,

           const pthread_rwlockattr_t *restrict attr);

参数:

       pthread_rwlock_t *restrict rwlock,  读写锁对象

    const pthread_rwlockattr_t *restrict attr 读写锁的属性,普通属性:NULL

返回值:

       成功:0

       失败:错误数

2.销毁读写锁

int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

参数:

       pthread_rwlock_t *rwlock 读写锁对象

3.读写锁操作

       #include <pthread.h>

函数原型:

       int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); // 读锁上锁(操作资源时共享)

       int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);// 写锁上锁(操作资源时互斥)

       int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);// 读写锁解锁

函数参数:

       以上三个函数的参数相同,都是读写锁对象

返回值:

       成功:0

       失败:错误数

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

// 定义读写锁对象
pthread_rwlock_t rwlock;

// 共有资源
int num=10;

void *func1(void *arg) // 任务函数1
{
	// 读锁上锁
	pthread_rwlock_rdlock(&rwlock);
	sleep(3);
	num = 50;
	printf("%s读锁上锁,num=%d\n", (char *)arg, num);
	// 解锁
	pthread_rwlock_unlock(&rwlock);
	// 退出线程
	pthread_exit(NULL);
}

void *func2(void *arg) // 任务函数2
{
	// 写锁上锁
	pthread_rwlock_wrlock(&rwlock);
	sleep(3);
	num = 100;
	printf("%s写锁上锁,num=%d\n", (char *)arg, num);
	// 解锁
	pthread_rwlock_unlock(&rwlock);
	// 退出线程
	pthread_exit(NULL);
}

void *func3(void *arg) // 任务函数3
{
	// 写锁上锁
	pthread_rwlock_wrlock(&rwlock);
	sleep(3);
	num = 300;
	printf("%s写锁上锁,num=%d\n", (char *)arg, num);
	// 解锁
	pthread_rwlock_unlock(&rwlock);
	// 退出线程
	pthread_exit(NULL);
}

void *func4(void *arg) // 任务函数4
{
	// 读锁上锁
	pthread_rwlock_rdlock(&rwlock);
	sleep(3);
	num = 400;
	printf("%s读锁上锁,num=%d\n", (char *)arg, num);
	// 解锁
	pthread_rwlock_unlock(&rwlock);
	// 退出线程
	pthread_exit(NULL);
}

int main(int argc, char const *argv[])
{
	// 初始化锁对象
	pthread_rwlock_init(&rwlock, NULL);
	// 创建线程
	pthread_t tid1, tid2, tid3, tid4;
	pthread_create(&tid1, NULL, func1, (void *)"我是线程1");
	pthread_create(&tid2, NULL, func2, (void *)"我是线程2");
	pthread_create(&tid3, NULL, func3, (void *)"我是线程3");
	pthread_create(&tid4, NULL, func4, (void *)"我是线程4");
	
	// 回收子线程
	pthread_join(tid1, NULL);
	pthread_join(tid2, NULL);
	pthread_join(tid3, NULL);
	pthread_join(tid4, NULL);

	return 0;
}

条件变量

1.初始化条件变量

       #include <pthread.h>

函数原型:

       int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);

参数:

       pthread_cond_t *cond, 条件变量的对象

pthread_condattr_t *cond_attr 条件变量的属性,普通属性设置为NULL

返回值:

       成功:0

       失败:非0

2.销毁条件变量

#include <pthread.h>

函数原型:

      int pthread_cond_destroy(pthread_cond_t *cond);

参数:

       pthread_cond_t *cond, 条件变量的对象

返回值:

       成功:0

       失败:非0

3.条件变量的操作

函数原型:

       int pthread_cond_signal(pthread_cond_t *cond); // 发送条件变量---发送给等待时间最长的线程

参数:

       pthread_cond_t *cond 条件变量对象的地址

返回值:成功:0  失败:非0

-------------------------------------------------------------------------------

函数原型:

       int pthread_cond_broadcast(pthread_cond_t *cond); // 发送条件变量,给所有正在等待条件变量的线程发送,但是最多也只有一个线程可以拿到,(所有等待的线程一起抢资源)

参数:

       pthread_cond_t *cond 条件变量对象的地址

返回值:成功:0  失败:非0

-------------------------------------------------------------------------------

函数原型:

       int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);// 等待条件变量,并且释放锁资源----当接收到条件变量时,会立即获取空闲状态下的互斥锁,往下执行

参数:

       pthread_cond_t *cond, 条件变量对象的地址

pthread_mutex_t *mutex 互斥锁对象

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

// 互斥锁资源
pthread_mutex_t m;
// 条件变量
pthread_cond_t cond;

int n;

// 线程1
void *func1(void *arg)
{
	printf("func1准备获取互斥锁\n");
	pthread_mutex_lock(&m);
	printf("func1已经获取互斥锁\n");

	if(n!=5) // 临时释放互斥锁,等待条件变量
	{
		printf("因为n!=5,所以临时释放互斥锁,等待条件变量!\n");
		pthread_cond_wait(&cond, &m);
		printf("获取了条件变量,重新拿到互斥锁\n");
		printf("继续执行!\n");
	}

	if(n==5)
		printf("n等于5,则继续执行\n");
	else
		while(1);

	// 释放锁资源
	pthread_mutex_unlock(&m);
	// 退出
	pthread_exit(NULL);
}

// 线程2
void *func2(void *arg)
{
	sleep(1);
	printf("func2准备获取互斥锁\n");
	pthread_mutex_lock(&m);
	printf("func2已经获取互斥锁\n");

	while(n<5)
	{
		printf("func2: n=%d\n", n++);
		sleep(1);
	}

	// 释放锁资源
	printf("func2已经处理完毕,马上释放资源\n");
	printf("释放锁资源\n");
	pthread_mutex_unlock(&m);
	printf("发送条件变量\n");
	pthread_cond_signal(&cond);

	// 退出
	pthread_exit(NULL);
}

int main(int argc, char const *argv[])
{
	// 初始化互斥锁和条件变量
	pthread_mutex_init(&m, NULL);
	pthread_cond_init(&cond, NULL);

	// 创建2个线程
	pthread_t tid[2];
	pthread_create(&tid[0], NULL, func1, NULL);
	pthread_create(&tid[1], NULL, func2, NULL);

	pause();
	
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值