一、多线程资源访问互斥
01.互斥锁(pthread_mutex_t)
卫生间模式:对资源进行上锁,某个人在使用资源时,其他人等待,使用完毕资源后,其他人使用
02.读写锁(pthread_rwlock_t)
基于互斥锁实现的一种锁应用,读共享,写独占,读写互斥,读写锁技术在原有的互斥锁基础上,提高了全局资源的利用率
pthread_rwlock_t lock;#读写锁类型
pthread_rwlock_init(pthread_rwlock_t* lockaddr, pthread_rwlock_t* attr)
pthread_rwlock_destroy(pthread_rwlock_t* lockaddr)
pthread_rwlock_wrlock(pthread_rwlock_t* lockaddr)
pthread_rwlock_rdlock(pthread_rwlock_t* lockaddr)
pthread_rwlock_unlock(pthread_rwlock_t* lockaddr)
读锁数量,ubuntu 12.04为255
03.自旋锁(旋转锁)
旋转锁互斥特征方面与互斥锁基本相同,不同之处在于,旋转不会挂起,以(R)的状态反复请求资源(就近原则不适用于旋转所),旋转锁的系统开销会比较大,因为所有的请求线程都是全速运行状态,如果不考虑系统开销,希望提高锁的使用频率,选择旋转锁,否则选择互斥锁
04.进程互斥锁(process_lock)
多进程模型下,如果多线程同时访问共享资源,一样会产生访问冲突,为了避免此冲突,可以使用互斥锁解决问题,这是互斥锁的多进程用法
我们可以通过修改互斥锁属性的方式将线程互斥锁改为进程互斥锁
pthread_mutexattr_t #互斥锁属性类型
1.定义互斥锁 pthread_mutex_t
2.定义互斥锁属性 pthread_mutexattr_t
3.初始化锁属性 pthread_mutexattr_init(pthread_mutex_t*) #初始化后默认为线程锁
4.修改互斥锁属性 pthread_mutexattr_setpshared(pthread_mutexattr_t*,int shared)#通过关键字将属性修改为进程锁
PTHREAD_PROCESS_SHARED #进程锁关键字 PTHREAD_PROCESS_PRIVATE #线程互斥关键字
5.互斥锁初始化 * 一定要使用自定义互斥锁属性初始化这把锁
05.文件读写锁(flock)
* 读共享,写独占,读写互斥,用于多进程或多线程访问共享文件,避免访问冲突
二、线程控制和调度
* 多线程流水线处理
条件变量相关的类型和函数
pthread_cond_t cd #条件变量类型
pthread_cond_init(pthread_cond_t* cd)#条件变量初始化
pthread_cond_destroy(pthread_cond_t* cd)#销毁释放条件变量
pthread_cond_wait(pthread_cond_t* cd,pthread_mutex_t* lock);
pthread_cond_signal(pthread_cond_t* cd)#唤醒一个挂起cd上的线程
* signal函数在多核处理器下,可能产生误唤醒问题
pthread_cond_broadcast(pthread_cond_t* cd)#唤醒所有挂起在cd的线程
举例:
两个线程操作全局资源,区分奇偶处理,相互唤醒,最终运算至目标值(执行次序,一人一次)
/*###################################################################
# mail: guoweiyelai@qq.com
# Created Time: Sat 16 Jul 2022 09:41:32 AM CST
#=============================================================*/
#include<stdio.h>
#include<pthread.h>
#include<string.h>
#include<unistd.h>
#include<sys/fcntl.h>
#include<sys/mman.h>
#include<sys/stat.h>
int code = 0;
pthread_cond_t Ocd,Jcd;
pthread_mutex_t lock;
void* J_jobs(void* arg)
{
for(int i=0;i<5000;i++){
pthread_mutex_lock(&lock);
if(code % 2==0)
pthread_cond_wait(&Jcd,&lock);
printf("J thread 0x%x ++code [%d]\n",(unsigned int)pthread_self(),++code);
pthread_mutex_unlock(&lock);
pthread_cond_signal(&Ocd);
}
}
void* O_jobs(void* arg)
{
for(int i=0;i<5000;i++){
pthread_mutex_lock(&lock);
if(code%2!=0)
pthread_cond_wait(&Ocd,&lock);
printf("O thread 0x%x ++code [%d]\n",(unsigned int)pthread_self(),++code);
pthread_mutex_unlock(&lock);
pthread_cond_signal(&Jcd);
}
}
int main()
{
pthread_mutex_init(&lock,NULL);
pthread_cond_init(&Jcd,NULL);
pthread_cond_init(&Ocd,NULL);
pthread_t tid;
pthread_create(&tid,NULL,J_jobs,NULL);
pthread_create(&tid,NULL,O_jobs,NULL);
while(1)sleep(1);
return 0;
}