设置方式
- 要有一片多进程能一起访问的共享内存。共享内存如何获得本文不做介绍,请自行google。
- 共享内存划一段大小为sizeof(pthread_mutex_t)的内存备用,记这片内存为mutex_reserve。把这片内存初始化为全0。
- 用pthread_mutex_t的指针mutex_p指向mutex_reserve。
- 构造phtread_mutex_t的初始化属性结构体pthread_mutexattr_t attr。
- 设置attr为PTHREAD_PROCESS_SHARED。
- 用attr初始化mutex_p指向的phtread_mutex_t。
答疑
1.用NULL初始化共享内存中的pthread_mutex_t可以吗?也就是省略掉步骤4和5。
答:不完全可以。不用被设置为PTHREAD_PROCESS_SHARED的attr初始化mutex,mutex也能保证互斥:实验表明,如果进程不调用sleep(),省略与不省略步骤4-5的结果是一样的,没有任何两个进程同时进入临界区。但是如果有一个进程带锁休眠(lock后调用sleep(1))。则它有可能使得其他进程不能再获得锁。永久阻塞在lock函数上。至于为什么我也不知道。不设置PTHREAD_PROCESS_SHARED可能还有其他不预期的事发生,所以还是设置PTHREAD_PROCESS_SHARED好。
2.看到一篇博客说,pthread_mutexattr_t也需要在共享内存中
答:不需要。它就是mutex初始化时的一个指导,这个指导在哪个位置并不重要。文章来源:https://www.toymoban.com/news/detail-812593.html
3. 第二点,不初始化那片内存为全0可以吗?
答:不可以。pthread_mutex_init有个规定,那就是它init的那片内存为全0。文章来源地址https://www.toymoban.com/news/detail-812593.html
参考代码
#include<pthread.h>
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h> //open
#include<sys/mman.h>
#include<string.h>
int id;
int main()
{
int fd=open("test_shared_lock_a",O_RDWR|O_CREAT,0777);
int result=ftruncate(fd,sizeof(pthread_mutex_t)+sizeof(pthread_mutexattr_t)+sizeof(int)*40);
pthread_mutex_t *mutex=(pthread_mutex_t *)mmap(NULL,sizeof(pthread_mutex_t)+sizeof(pthread_mutexattr_t)+sizeof(int)*40,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
memset(mutex,0,sizeof(pthread_mutex_t)+sizeof(pthread_mutexattr_t)+sizeof(int)*40);
int* num=(int*)((char*)mutex+sizeof(pthread_mutex_t)+sizeof(pthread_mutexattr_t));
for(int i=0;i<40;i++)
{
num[i]=0;
}
pthread_mutexattr_t* attr=NULL;
/* 下面三行,把pthread_mutexattr_t放在了共享内存中。*/
// attr=(pthread_mutexattr_t*)((char*)mutex+sizeof(pthread_mutex_t));
// pthread_mutexattr_init(attr);
// pthread_mutexattr_setpshared(attr, PTHREAD_PROCESS_SHARED);
/* 下面四行,pthread_mutexattr_t没有放在共享内存中。*/
pthread_mutexattr_t s;
attr=&s;
pthread_mutexattr_init(attr);
pthread_mutexattr_setpshared(attr, PTHREAD_PROCESS_SHARED);
// 上面7行如果都注释,则为不使用attr初始化mutex。
pthread_mutex_init(mutex,attr);
//创建39个子进程。并且每个进程获得一个id。
for(int i=0;i<39;i++)
{
id=i+1;
int pid=fork();
if(pid==0)
{
break;
}
else
{
if(id==39)
{
id=0;
}
}
}
//每个进程报告自己的pid。
printf("%d report!\n",getpid());
//if(id!=0)
{
//开始检测是否有多个进程同时进入临界区。
int j=1;
while(j-->0)
{
printf("%d try to lock!\n",getpid());
pthread_mutex_lock(mutex);
printf("%d get lock\n",getpid());
//拿到锁后,在对应位置做标记,表示自己进入临界区。
num[id]=1;
int sum=0;
for(int i=0;i<40;i++)
{
sum+=num[i];
}
if(sum>1)
{
printf("%d lock_failed!\n",getpid()); //如果有两个进程同时进入临界区,sum必定大于0。
}
else
{
printf("%d test_ok\n",getpid()); //如果sum为1,说明只有一个进程进入临界区。
}
num[id]=0;
sleep(1);
pthread_mutex_unlock(mutex);
}
}
}
到了这里,关于多进程共享的pthread_mutex_t的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!