虚拟机Linux下的信号量与共享内存

虚拟机Linux下的信号量与共享内存

  • 信号量
    • 共享内存

信号量

ulimit -a 查看限制信息
ulimit -代号 更改大小(只能临时改变)

信号量的一个更正式的定义:
特殊变量,只可以改变,对信号量加一、减一的操作都是原子操作,一般取正数值,它的作用:同步资源,用于管理对资源的访问。
含有两种操作:
P (信号量变量):用于等待
V (信号量变量):用于发送信号
这两种操作的定义如下:

P(sv) 如果sv的值大于零,就给它减去一;如果只为零,就挂起该进程的执行
V(sv) 如果有其他进程因等待sv而被挂起,就让他恢复运行;如果没有其他进程因等待sv而被挂起,就给他加上一

二值信号量:0 ,1;用这两个值来控制进程的执行和挂起状态;

虚拟机Linux下的信号量与共享内存_第1张图片

定义两个信号量的具体代码实现:
sem.h文件

#include
#include
#include
#include
#include
#include

union semun
{
     
    int val;
};

void sem_init();
void sem_p(int index);
void sem_v(int index);
void sem_destroy();

sem.c文件

#include"sem.h"

#define MAX_SEM 2
static int semid = -1;

void sem_init()
{
     
    semid=semget((key_t)1234,MAX_SEM,IPC_CREAT|IPC_EXCL|0600);
    if( semid == -1 )
    {
     
        semid=semget((key_t)1234,MAX_SEM,0600);
        if (semid == -1)
        {
     
            perror("semget error");
        }
    }
    else
    {
     
        union semun a;
        int arr[]={
     1,0};
        int i=0;
        for( ;i<MAX_SEM;i++)
        {
     
            a.val=arr[i];
            if( semctl( semid,i,SETVAL,a) == -1)
            {
     
                perror("semctl error ");
            }
        }
    }
}
void sem_p(int index)
{
     
    if(index<0||index>MAX_SEM)
    {
     
        printf("p argc error");
        return ;
    }

    struct sembuf buf;
    buf.sem_num=index;
    buf.sem_op=-1;//-1  代表p操作
    buf.sem_flg = SEM_UNDO;

    if (semop(semid,&buf,1)==-1)
    {
     
        perror("semop p error");
    }

}
void sem_v(int index)
{
     
    if(index<0||index>MAX_SEM)
    {
     
        printf("v argc error");
        return ;
    }

    struct sembuf buf;
    buf.sem_num=index;
    buf.sem_op= 1;//  1  代表v操作
    buf.sem_flg = SEM_UNDO;

    if (semop(semid,&buf,1)==-1)
    {
     
        perror("semop v error");
    }
}
void sem_destroy()
{
     
    if( semctl(semid,0,IPC_RMID)==-1)
    {
     
        perror("semctl error");
    }
}

共享内存

根据《Linux程序设计》 中文第四版 第12章编写。

共享内存为在多个进程之间共享和传递数据提供了一种有效的方式。由于它并未提供同步机制,所以我们通常需要通过其他机制来同步对共享内存的访问。下面我们就通过信号量实现对它的控制,主要用到以下几个函数:
shmget() 创建、获取共享内存
shmat() 映射(实现逻辑地址链接共享内存)
shmdt()断开链接
shmctl()控制共享内存(通常为删除)

实现信号量对共享内存的控制主要有以下几个步骤:
1、根据实际需求确定信号量数目;
2、赋初始值(即前面提到的变量sv);
3、p、v操作同步;

以下是两个信号量s1(初始值为1),s2(初始值为0)的具体实现代码

输入端 a.c

#include
#include
#include
#include
#include
#include
#include"sem.h"

int main()
{
     
    int shmid=shmget((key_t)1234,256,IPC_CREAT|0600);//开辟共享空间
    assert(shmid != -1);

    char * s=(char*)shmat(shmid,NULL,0);//创建映射
    sem_init();

    while(1)
    {
     
        char buff[128]={
     0};
        printf("input:");
        fgets(buff,128,stdin);
        
        sem_p(0);

        strcpy(s,buff);
        
        sem_v(1);
        if(strncmp(buff,"end",3)==0)
        {
     
            break;
        }
    }
    exit(0);
}

输出端 b.c

#include
#include
#include
#include
#include
#include
#include "sem.h"
int main()
{
     
    int shmid=shmget((key_t)1234,256,IPC_CREAT|0600);//开辟共享空间
    assert(shmid != -1);

    char * s=(char*)shmat(shmid,NULL,0);//创建映射
    
    assert(s != NULL);
    
    sem_init();

    while(1)
    {
     
        sem_p(1);

        if(strncmp(s,"end",3)==0)
        {
     
            break;
        }
        printf("s=%s\n",s);

        sem_v(0);
    }

    shmdt(s);

    sem_destroy();

    if( shmctl(shmid,IPC_RMID,NULL)== -1)
    {
     
        perror("shmctl error!");
    }

    exit(0);
}


执行结果:
虚拟机Linux下的信号量与共享内存_第2张图片

你可能感兴趣的:(虚拟机Linux下的信号量与共享内存)