题目概述
父进程中使用fork()创建一个子进程,使两进程能够互斥访问一个变量并改写其值。
代码
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h> //关于信号量的库
#include <fcntl.h> //关于文件管理的库(有名信号量会用到)
#include <sys/shm.h> //关于共享内存的库
sem_t *sem; //创建一个信号量指针
int shmID; //创建存储共享内存标识的变量
int* shm = NULL; //指向共享内存首地址的指针
void user_delay(int td)
{
for(int i = 0;i< td;i++)
{
for(int j = 0;j< td;j++)
{
for(int t = 0;t< td;t++);
}
}
}
void subp1( )
{
sem_wait(sem); //等待信号量
int temp = 0;
shm = shmat(shmID,0, 0); //通过id使当前 进程/线程 挂载到共享内存
for(int i =0;i<50;i++)
{
user_delay(100);
temp = *shm;
user_delay(100);
temp ++;
user_delay(100);
*shm = temp;
user_delay(100);
}
shmdt(&shm); //卸载共享内存
sem_post(sem); //释放信号量
}
//内容同subp1
void subp2( )
{
sem_wait(sem);
int temp = 0;
shm = shmat(shmID, 0, 0);
for(int i =0;i<50;i++)
{
user_delay(100);
temp = *shm;
user_delay(100);
temp ++;
user_delay(100);
*shm = temp;
user_delay(100);
}
shmdt(&shm);
sem_post(sem);
}
int main()
{
shmID = shmget(1234, sizeof(int), 0666|IPC_CREAT); //创建共享内存,(标识值,尺寸,权限)
shm = shmat(shmID, 0, 0); //挂载到共享内存
*shm = 0; //为共享内存赋值
shmdt(&shm); //卸载共享内存
sem = sem_open("name_sem",O_CREAT|O_RDWR,0666,1); //创建有名信号量 (文件名,创建|打开,权限,值),返回信号量地址
pid_t pid = fork();
if(pid == 0)
{
subp1( );
exit(0);
}
subp2( );
wait(NULL);
printf("A = %d\n",*shm);
sem_unlink("name_sem"); //断开连接,删除有名信号量文件
return 0;
}
总结
- 有名信号量会在系统中创建一个信号里文件,以达到进程间的共享。
- 共享内存在进程挂载后要记得及时卸载。