linux网络编程之System V信号量(一) 封装一个信号量集操作函数的工具

与消息队列和共享内存一样,信号量集也有自己的数据结构:

struct semid_ds {

struct ipc_perm sem_perm;  /* Ownership and permissions */

time_t    sem_otime; /* Last semop time */

time_t    sem_ctime; /* Last change time */

unsigned short  sem_nsems; /* No. of semaphores in set */

};

同样地,第一个条目也是共有的ipc 对象内核结 构,剩下的是私有成员。

Each semaphore in a semaphore set has the following associated values:

          unsigned short  semval;   /* semaphore value */

          unsigned short  semzcnt;  /* # waiting for zero */

          unsigned short  semncnt;  /* # waiting for increase */

          pid_t           sempid;   /* process that did last op */

 

即每一个在信号集中的信号量都有上述4个相关的变量。

1、semval :当前某信号量的资源数目

2、semzcnt:当sem_op(见 struct sembuf)为0,且semop 函数没有设置IPC_NOWAIT 标志,且当前semval 不为0 ,此时进程会阻塞等待直到4个事件发生,具体可man 2 semop 一下,然后semzcnt 会加1,表示等待这个信号量的资源变为 0的进程数加1。

3、semncnt:当sem_op(见 struct sembuf)< 0,且semop 函数没有设置IPC_NOWAIT 标志,且 当前semval < |sem_op| ,此时进程会阻塞等待直到4个事件发生,具体可man 2 semop 一下,然后semncnt 会加1,表 示等待这个信号量的资源增加的进程数加1。

4、当正确执行了semop 函数,则每个信号量的sempid 参数都被设置为 改变此信号量的进程pid。

以下是几个信号量集操作函数:

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/sem.h>

int semget(key_t key, int nsems, int semflg);

int semctl (int semid, int semnum, int cmd, ...);

int semop(int semid, struct sembuf *sops, unsigned nsops);

功 能:用来创建和访问一个信号量集

原型int semget(key_t key, int nsems, int semflg);

参数

key: 信号集的名 字

nsems:信号集中信号量的个数

semflg: 由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样 的

返回值:成功返回一个非负整数,即该信号集的标识码;失败返回-1

功能:用于控制信号量集

原型int semctl(int semid, int semnum, int cmd, ...);

参数

semid:由semget返回的信号集标识码

semnum:信号集中信号 量的序号,从0开始编号

cmd:将要采取的动作(有三个可取值)

最后一个参数是 union semun,具体成员根据cmd 的 不同而不同

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) */

          };

返回值:成功返回0;失败返回-1

时间: 2024-11-02 20:10:30

linux网络编程之System V信号量(一) 封装一个信号量集操作函数的工具的相关文章

linux网络编程之System V 信号量(二)

用信号量实现进程互斥示例和解决哲学家就餐问题 一.我们在前面讲进程间通信的时候提到过进程互斥的概念,下面写个程序来模拟一下,程序流程如下图: 即父进程打印字 符O,子进程打印字符X,每次打印一个字符后要sleep 一下,这里要演示的效果是,在打印程序的边界有PV操作,故每个进 程中间sleep 的时间即使时间片轮转到另一进程,由于资源不可用也不会穿插输出其他字符,也就是说O或者X字符都会是成 对出现的,如OOXXOOOOXXXXXXOO.... 程序如下: #include<sys/types.

linux网络编程之System V 信号量(三)

基于生产者-消费者模型实现先进先出的共享内存段 生产者消费者问题:该问题描述了两个共享固定大小缓冲区的进程--即所谓的"生产者"和"消费者"--在实际运 行时会发生的问题.生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程.与此同时,消费者也在缓冲区 消耗这些数据.该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据. 我们可以用信号量解决生产者消费者问题,如下图: 定义3个信号量,sem_full 和 sem_emp

linux网络编程之System V 共享内存和系列函数

跟消息队列一样,共享内存也有自己的数据结构,如下: struct shmid_ds { struct ipc_perm shm_perm;    /* Ownership and permissions */ size_t     shm_segsz;   /* Size of segment (bytes) */ time_t     shm_atime;   /* Last attach time */ time_t     shm_dtime;   /* Last detach time

linux 网络编程之TIME_WAIT状态

                                                         Linux 网络编程之TIME_WAIT状态                                                               刚刚开始看TCP socket的4次握手终止流程图的时候,对于最后的TIME_WAIT状态不是很理解.现在在回过头来研究,发现TIME_WAIT状态是一个很微妙状态.之所以设计TIME_WAIT状态的原因有2个原因:

Linux网络编程之UDP Socket程序示例_C 语言

在网络传输协议中,TCP协议提供的是一种可靠的,复杂的,面向连接的数据流(SOCK_STREAM)传输服务,它通过三段式握手过程建立连接.TCP有一种"重传确认"机制,即接收端收到数据后要发出一个肯定确认的信号,发送端如果收到接收端肯定确认的信号,就会继续发送其他的数据,如果没有,它就会重新发送. 相对而言,UDP协议则是一种无连接的,不可靠的数据报(SOCK_DGRAM)传输服务.使用UDP套接口不用建立连接,服务端在调用socket()生成一个套接字并调用bind()绑定端口后就可

linux网络编程之posix 线程(三)

posix 信号量与互斥锁 示例生产者--消费者问题 一.posix 信号量 信号量的概念参见这里(http://www.bianceng.cn/OS/Linux/201308/37243.htm).前面也讲过system v 信号量,现在来说说posix 信号量. system v 信号量只能用于进程间同步,而posix 信号量除了可以进程间同步,还可以线程间同步.system v 信号量每次PV操作可以是N,但Posix 信号量每次PV只能是1.除此之外,posix 信号量还有命名和匿名之分

linux网络编程之POSIX消息队列和系列函数

一.在前面介绍了system v 消息队列的相关知识,现在来稍微看看posix 消息队列. 其实消息队列就是一个可 以让进程间交换数据的场所,而两个标准的消息队列最大的不同可能只是api 函数的不同,如system v 的系列函数是 msgxxx,而posix 是mq_xxx.posix 消息队列也有一些对消息长度等的限制,man 7 mq_overview: simba@ubuntu:~/Documents/code/linux_programming/UNP/posix$ cat /proc

linux网络编程之POSIX共享内存和系列函数

在前面介绍了system v 共享内存的相关知识,现在来稍微看看posix 共享内存 和系列函数. 共享内存简单来说 就是一块真正的物理内存区域,可以使用一些函数将这块区域映射到进程的地址空间进行读写,而posix 共享内存与system v 共享内存不同的是它是用虚拟文件系统(tmpfs)实现的,已经挂载在/dev/shm 下面.man 7 shm_overview 下面 来看系列函数,编译时候加上 -lrt 选项,即连接librt 库 (实时库) 功能:用来创建或打开一个共享内存对象 原型

Linux网络编程之TCP协议

server.c: #include <stdlib.h>  #include <stdio.h>  #include <errno.h>  #include <string.h>  #include <netdb.h>  #include <sys/types.h>  #include <netinet/in.h>  #include <sys/socket.h>  #define portnumber 88