言之者无罪,闻之者足以戒。 ——《诗序》
3、线程的同步属性
就像线程有属性一样,线程的同步互斥量也有属性,比较重要的是进程共享属性和类型属性。互斥量的属性用pthread_mutexattr_t类型的数据表示,当然在使用之前必须进行初始化,使用完成之后需要进行销毁:
(1)、pthread_mutexattr_init互斥量的属性初始化函数
int pthread_mutexattr_init(pthread_mutexattr_t*attr)
参数:属性
返回值:成功返回0,失败返回错误码
(2)、pthread_mutexattr_destroy互斥量销毁函数
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
参数:属性
返回值:成功返回0,失败返回错误码
进程共享属性有两种值:PTHREAD_PROCESS_PRIVATE,这个是默认值,同一个进程中的多个线程访问同一个同步对象,
PTHREAD_PROCESS_SHARED, 这个属性可以使互斥量在多个进程中进行同步,如果互斥量在多进程的共享内存区域,那么具有这个属性的互斥量可以同步多进程
(3)、pthread_mutexattr_setpshared设置互斥量进程共享属性
int pthread_mutexattr_setpshared(const pthread_mutexattr_t *attr, int pshared)
第一个参数:共享属性
第二个参数:设置是否共享
返回值:成功返回0,失败返回错误码
(4)、pthread_mutexattr_getpshared获得互斥量进程共享属性
int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict attr, int *restrict pshared)
第一个参数:共享属性
第二个参数:获得属性
返回值:成功返回0,失败返回错误码
进程共享属性需要检测系统是否支持,可以检测宏_POSIX_THREAD_PROCESS_SHARED(#ifdef和#endif检测)
(5)、pthread_mutexattr_settype设置互斥量的类型属性
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
第一个参数:类型属性
第二个参数:互斥量类型
返回值:成功返回0,失败返回错误码
(6)、pthread_mutexattr_gettype获取互斥量的类型属性
int pthread_mutexattr_gettype(pthread_mutexattr_t *restrict attr, int *restrict type)
第一个参数:类型属性
第二个参数:互斥量类型
返回值:成功返回0,失败返回错误码
下面来看一下程序代码:
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
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);
}
读写锁也有属性,它只有一个进程共享属性:
(7)、pthread_rwlockattr_init读写锁属性初始化函数
int pthread_rwlockattr_init(pthread_rwlockattr_t *attr)
第一个参数:属性
返回值:成功返回0,失败返回错误码
(8)、pthread_rwlockattr_destroy读写锁属性销毁函数
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr)
第一个参数:属性
返回值:成功返回0,失败返回错误码
(9)、pthread_rwlockattr_setpshared设置读写锁进程共享属性
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared)
第一个参数:共享属性
第二个参数:设置是否共享
返回值:成功返回0,失败返回错误码
(10)、pthread_rwlockattr_getpshared获取读写锁进程共享属性
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int *restrict pshared)
第一个参数:共享属性
第二个参数:获取属性
返回值:成功返回0,失败返回错误码
条件变量也有进程共享属性:
(11)、pthread_condattr_init条件变量属性初始化函数
int int pthread_condattr_init(pthread_condattr_t *attr)
第一个参数:属性
返回值:成功返回0,失败返回错误码
(12)、pthread_condattr_destroy条件变量属性销毁函数
int pthread_condattr_destroy(pthread_condattr_t *attr)
第一个参数:属性
返回值:成功返回0,失败返回错误码
(13)、pthread_condattr_setpshared设置条件变量属性函数
int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared)
第一个参数:共享属性
第二个参数:设置是否共享
返回值:成功返回0,失败返回错误码
(14)、pthread_condattr_getpshared获取条件变量属性函数
int pthread_condattr_getpshared(const pthread_condattr_t *restrict attr, int *restrict pshared)
第一个参数:共享属性
第二个参数:获取的共享
返回值:成功返回0,失败返回错误码