一、互斥量的属性
就像线程有属性一样,线程的同步互斥量也有属性,比较重要的是进程共享属性和类型属性。互斥量的属性用pthread_mutexattr_t类型的数据表示,当然在使用之前必须进行初始化,使用完成之后需要进行销毁:
1)、互斥量初始化
int pthread_mutexattr_init(pthread_mutexattr_t *attr);
2)、互斥量销毁
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
二、互斥量的进程共享属性
进程共享属性有两种值:
1)、PTHREAD_PROCESS_PRIVATE,这个是默认值,同一个进程中的多个线程访问同一个同步对象
2)、PTHREAD_PROCESS_SHARED, 这个属性可以使互斥量在多个进程中进行同步,如果互斥量在多进程的共享内存区域,那么具有这个属性的互斥量可以同步多进程
设置互斥量进程共享属性
int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict attr, int *restrict pshared);
int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared);
进程共享属性需要检测系统是否支持,可以检测宏_POSIX_THREAD_PROCESS_SHARED
三、互斥量的类型属性
类型属性
互斥量类型 | 没有解锁时再次加锁 | 不占用是解锁 | 已解锁时解锁 |
---|---|---|---|
PTHREAD_MUTEX_NORMAL | 死锁 | 未定义 | 未定义 |
PTHREAD_MUTEX_ERRORCHEK | 返回错误 | 返回错误 | 返回错误 |
PTHREAD_MUTEX_RECURSIVE | 允许 | 返回错误 | 返回错误 |
PTHREAD_MUTEX_DEFAULT | 未定义 | 未定义 | 未定义 |
获取/设置互斥量的类型属性
int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict attr, int *restrict type);
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);
三、读写锁与条件变量的属性**
1、读写锁也有属性,它只有一个进程共享属性 。
读写锁属性初始化
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);
int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
设置读写锁进程共享属性
int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *restrict attr, int *restrict pshared);
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared);
2、条件变量也有进程共享属性
条件变量属性初始化
int pthread_condattr_destroy(pthread_condattr_t *attr);
int pthread_condattr_init(pthread_condattr_t *attr);
设置条件变量属性
int pthread_condattr_getpshared(const pthread_condattr_t *restrict attr, int *restrict pshared);
int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared);
四、实例
互斥量属性使用
1、程序框架
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <iostream>
#include <queue>
#include <sys/types.h>
#include <sys/stat.h>
//#include <sys/mman.h>
#include <fcntl.h>
#include "include/pthread.h"
#ifndef _WIN64
#pragma comment(lib,".\\lib32\\pthreadVC2.lib")
#else
#pragma comment(lib,".\\lib64\\pthreadVC2.lib")
#endif
/*
在Windows下无法运行,没有在Linux下测试。
就像线程有属性一样,线程的同步互斥量也有属性,比较重要的是进程共享属性和类型属性。互斥量的属性用pthread_mutexattr_t类型的数据
表示,当然在使用之前必须进行初始化,使用完成之后需要进行销毁:
1)、互斥量初始化
int pthread_mutexattr_init(pthread_mutexattr_t *attr);
2)、互斥量销毁
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
进程共享属性有两种值:
1)、PTHREAD_PROCESS_PRIVATE,这个是默认值,同一个进程中的多个线程访问同一个同步对象
2)、PTHREAD_PROCESS_SHARED, 这个属性可以使互斥量在多个进程中进行同步,如果互斥量在多进程的共享内存区域,那么具有这个属性的
互斥量可以同步多进程
设置互斥量进程共享属性
int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict attr, int *restrict pshared);
int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared);
进程共享属性需要检测系统是否支持,可以检测宏_POSIX_THREAD_PROCESS_SHARED
类型属性
互斥量类型 没有解锁时再次加锁 不占用是解锁 已解锁时解锁
PTHREAD_MUTEX_NORMAL 死锁 未定义 未定义
PTHREAD_MUTEX_ERRORCHEK 返回错误 返回错误 返回错误
PTHREAD_MUTEX_RECURSIVE 允许 返回错误 返回错误
PTHREAD_MUTEX_DEFAULT 未定义 未定义 未定义
获取/设置互斥量的类型属性
int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict attr, int *restrict type);
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);
1、读写锁也有属性,它只有一个进程共享属性 读写锁属性初始化 int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr); int pthread_rwlockattr_init(pthread_rwlockattr_t *attr); 设置读写锁进程共享属性 int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *restrict attr, int *restrict pshared); int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared); 2、条件变量也有进程共享属性
条件变量属性初始化
int pthread_condattr_destroy(pthread_condattr_t *attr);
int pthread_condattr_init(pthread_condattr_t *attr);
设置条件变量属性
int pthread_condattr_getpshared(const pthread_condattr_t *restrict attr, int *restrict pshared);
int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared);
*/
#define _POSIX_THREAD_PROCESS_SHARED
int main()
{
char *shm = "myshm";
char *shm1 = "myshm1";
int shm_id, shm_id1;
char *buf;
pid_t pid;
pthread_mutex_t *mutex;
pthread_mutexattr_t mutexattr;
//打开共享内存
shm_id1 = shm_open(shm1, O_RDWR | O_CREAT, 0644);
//调整共享内存大小
ftruncate(shm_id1, 100);
//映射共享内存,MAP_SHARED属性表明,对共享内存的任何修改都会影响其他进程
mutex = (pthread_mutex_t *)mmap(NULL, 100, PROT_READ | PROT_WRITE, MAP_SHARED, shm_id1, 0);
pthread_mutexattr_init(&mutexattr);
#ifdef _POSIX_THREAD_PROCESS_SHARED
pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED);
#endif
pthread_mutex_init(mutex, &mutexattr);
//打开共享内存
shm_id = shm_open(shm, O_RDWR | O_CREAT, 0644);
//调整共享内存大小
ftruncate(shm_id, 100);
//映射共享内存,MAP_SHARED属性表明,对共享内存的任何修改都会影响其他进程
buf = (char *)mmap(NULL, 100, PROT_READ | PROT_WRITE, MAP_SHARED, shm_id, 0);
pid = fork();
if (pid == 0)
{
//休眠1s,让父进程先运行
Sleep(1);
printf("I'm child proccess\n");
pthread_mutex_lock(mutex);
//将共享内存内存修改为hello
memcpy(buf, "hello", 6);
printf("child buf is : %s\n", buf);
pthread_mutex_unlock(mutex);
}
else if (pid > 0)
{
printf("I'm parent proccess\n");
pthread_mutex_lock(mutex);
//修改共享内存到内容,改为world
memcpy(buf, "world", 6);
Sleep(3);
printf("parent buf is : %s\n", buf);
pthread_mutex_unlock(mutex);
}
pthread_mutexattr_destroy(&mutexattr);
pthread_mutex_destroy(mutex);
//解除映射
munmap(buf, 100);
//消除共享内存
shm_unlink(shm);
//解除映射
munmap(mutex, 100);
//消除共享内存
shm_unlink(shm1);
}