zoukankan      html  css  js  c++  java
  • linux第11天 共享内存和信号量

     今天主要学习了共享内存和信号量

    在此之前,有个管道问题

    ls | grep a

    整句话的意思是将ls输出到管道的写端,而流通到另一端的读端,grep a则是从管道的读端读取相关数据,再做筛选

    共享内存

    int shmget(key_t key, size_t size, int flag);

    key: 标识符的规则
    size:共享存储段的字节数
    flag:读写的权限 0666 | O_CREAT
    返回值:成功返回共享存储的id,失败返回-1

    shmat
    void *shmat(int shmid, const void *shmaddr, int flag);
    shmid:共享存储的id
    shmaddr:一般为0,表示连接到由内核选择的第一个可用地址上,否则,如果flag没有指定SHM_RND,则连接到addr所指定的地址上,如果flag为SHM_RND,则地址取整
    flag:如前所述,一般为0
    返回值:如果成功,返回共享存储段地址,出错返回-1

    shmaddr为NULL,核心自动选择一个地址
    shmaddr不为NULL且shmflg无SHM_RND标记,则以shmaddr为连接地址。
    shmaddr不为NULL且shmflg设置了SHM_RND标记,则连接的地址会自动向下调整为SHMLBA的整数倍。公式:shmaddr - (shmaddr % SHMLBA)
    shmflg=SHM_RDONLY,表示连接操作用来只读共享内存

    shmdt

    行为与shmat相反,取消共享内存映射

    shmctl函数
      功能:用于控制共享内存
      原型
      int shmctl(int shmid, int cmd, struct shmid_ds  *buf);
      参数
      shmid:由shmget返回的共享内存标识码
      cmd:将要采取的动作(有三个可取值)
      buf:指向一个保存着共享内存的模式状态和访问权限的数据结构
      返回值:成功返回0;失败返回-1

    共享内存的创建与操作

    	int shmid = shmget(0x159357, 4, 0666 | IPC_CREAT);	
    	if (shmid < 0)
    		perror("shmget");
    
    	void *p = NULL;
    	p = shmat(shmid, NULL, 0);
    	(*(int *)p) = 0;
    		
    	shmdt(p);
    

      

    信号量 

    信号量可以看成一个结构体,里面包含两个字段同数据.

    1.可以使用的资源数据.当资源数用完,没有资源释放,再次访问资源内核将阻塞进程

    2.被阻塞的进程队列.

    struct semaphore
    {
      int value;
      pointer_PCB queue;
    }

    信号量值含义
    S>0:S表示可用资源的个数
    S=0:表示无可用资源,无等待进程
    S<0:|S|表示等待队列中进程个数

    P原语
    P(s)
    {
      s.value = s.value--;
      if (s.value< 0)
      {
        该进程状态置为等待状状态
        将该进程的PCB插入相应的等待队列s.queue末尾
      }
    }

    V原语
    V(s)
    {
      s.value = s.value++;
      if (s.value< =0)
      {
        唤醒相应等待队列s.queue中等待的一个进程
        改变其状态为就绪态
        并将其插入就绪队列
      }
    }

    semget函数
    功能:用来创建和访问一个信号量集
    原型
    int semget(key_t key, int nsems, int semflg);
    参数
    key: 信号集的名字
    nsems:信号集中信号量的个数
    semflg: 由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的
    返回值:成功返回一个非负整数,即该信号集的标识码;失败返回-1

    shmctl函数
    功能:用于控制信号量集
    原型
    int semctl(int semid, int semnum, int cmd, ...);
    参数
    semid:由semget返回的信号集标识码
    semnum:信号集中信号量的序号
    cmd:将要采取的动作(有三个可取值)
    最后一个参数根据命令不同而不同
    返回值:成功返回0;失败返回-1

    semop函数
    功能:用来创建和访问一个信号量集
    原型
    int semop(int semid, struct sembuf *sops, unsigned nsops);
    参数
    semid:是该信号量的标识码,也就是semget函数的返回值
    sops:是个指向一个结构数值的指针
    nsops:信号量的个数
    返回值:成功返回0;失败返回-1

    semop函数续
    sembuf结构体:
    struct sembuf {
      short sem_num;
      short sem_op;
      short sem_flg;
    };
    sem_num是信号量的编号。
    sem_op是信号量一次PV操作时加减的数值,一般只会用到两个值,一个是“-1”,也就是P操作,等待信号量变得可用;另一个是“+1”,也就是我们的V操作,发出信号量已经变得可用
    sem_flag的两个取值是IPC_NOWAIT或SEM_UNDO,一般取0

    封装好的信号操作函数

    union semun {
       int              val;    /* Value for SETVAL */
       struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
       unsigned short  *array;  /* Array for GETALL, SETALL */
       struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                   (Linux-specific) */
    };
    
    
    int semCreateOrGet(key_t key)
    {
    	int semid = 0;
    	semid = semget(key, 1, 0666 | IPC_CREAT);
    	if (semid < 0)
    		ERR_EXIT("semget");
    		
    	return semid;
    }
    
    int semSetValue(int semid, int val)
    {
    	int ret = 0;
    	union semun su;
    	su.val = val;
    	ret = semctl(semid, 0, SETVAL, su);
    	return ret;
    	
    }
    
    
    int semGetValue(int semid)
    {
    	int ret = 0;
    	union semun su;
    	ret = semctl(semid, 0, GETVAL, su);
    	printf("目前资源数为%d
    ", su.val);
    	return ret;
    	
    }
    
    int sem_p(int semid)
    {
    	int ret = 0;
    	struct sembuf sbuf = { 0, -1, 0 };
    	ret  = semop(semid, &sbuf, 1);
    	return ret;
    }
    
    int sem_v(int semid)
    {
    	int ret = 0;
    	struct sembuf sbuf = { 0, 1, 0 };
    	ret  = semop(semid, &sbuf, 1);
    	return ret;
    }
    

      

  • 相关阅读:
    网页加速的14条优化法则 网站开发与优化
    .NET在后置代码中输入JS提示语句(背景不会变白)
    C语言变量声明内存分配
    SQL Server Hosting Toolkit
    An established connection was aborted by the software in your host machine
    C语言程序设计 2009春季考试时间和地点
    C语言程序设计 函数递归调用示例
    让.Net 程序脱离.net framework框架运行
    C语言程序设计 答疑安排(2009春季 110周) 有变动
    软件测试技术,软件项目管理 实验时间安排 2009春季
  • 原文地址:https://www.cnblogs.com/c-slmax/p/5277173.html
Copyright © 2011-2022 走看看