操作系统学习:关于进程同步、有名信号量、共享内存

题目概述

父进程中使用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;
}

总结

  • 有名信号量会在系统中创建一个信号里文件,以达到进程间的共享。
  • 共享内存在进程挂载后要记得及时卸载。

此文是在下初次学习所写,必有不足,望指正!

发布了14 篇原创文章 · 获赞 26 · 访问量 3292

猜你喜欢

转载自blog.csdn.net/weixin_44338553/article/details/104907943