互斥锁
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;
}