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

在此之前,有个管道问题

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\n", 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;
}

  

linux第11天 共享内存和信号量的更多相关文章

  1. 浅析Linux下进程间通信:共享内存

    浅析Linux下进程间通信:共享内存 共享内存允许两个或多个进程共享一给定的存储区.因为数据不需要在客户进程和服务器进程之间复制,所以它是最快的一种IPC.使用共享内存要注意的是,多个进程之间对一给定 ...

  2. 第三十三章 System V共享内存与信号量综合

    用信号量解决生产者.消费者问题 实现shmfifo ip.h #ifndef _IPC_H #define _IPC_H #include <unistd.h> #include < ...

  3. C实现进程间通信(管道; 共享内存,信号量)

    最近学习了操作系统的并发:以下是关于进程间实现并发,通信的两个方法. 例子: 求100000个浮点数的和.要求: (1)随机生成100000个浮点数(父进程). (2)然后创建4个后代进程,分别求25 ...

  4. Linux 进程间通信(管道、共享内存、消息队列、信号量)

           进程通信 : 不同进程之间传播或交换信息    为什么要进程通信呢? 协同运行,项目模块化 通信原理 : 给多个进程提供一个都能访问到的缓冲区. 根据使用场景,我们能划分为以下几种通信 ...

  5. 8.7 进程间的通讯:管道、消息队列、共享内存、信号量、信号、Socket

    进程间的通讯 进程间为什么需要通讯? 共享数据.数据传输.消息通知.进程控制 进程间的通讯有哪些类型? 首先,联系前面讲过的知识,进程之间的用户地址空间是相互独立的,不能进行互相访问,但是,内核空间却 ...

  6. Linux环境进程间通信(五): 共享内存(下)

    linux下进程间通信的几种主要手段: 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允 ...

  7. Linux环境进程间通信(五): 共享内存(上)

    linux下进程间通信的几种主要手段: 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允 ...

  8. ubuntu linux c学习笔记----共享内存(shmget,shmat,shmdt,shmctl)

    shmget int shmget(key_t key, size_t size, int flag); key: 标识符的规则 size:共享存储段的字节数 flag:读写的权限 返回值:成功返回共 ...

  9. Linux IPC System V 共享内存

    模型 #include<sys/types.h> #include<sys/ipc.h> #include<sys/shm.h> ftok() //获取key值 s ...

随机推荐

  1. php YAF

    Yaf 的特点: 用C语言开发的PHP框架, 相比原生的PHP, 几乎不会带来额外的性能开销. 所有的框架类, 不需要编译, 在PHP启动的时候加载, 并常驻内存. 更短的内存周转周期, 提高内存利用 ...

  2. This system is not registered with RHN

    在红帽EL5上运行yum,提示“This system is not registered with RHN”,意思是没有在官网上注册,不能下载RH的软件包,替代方案是采用centos源. 1.卸载r ...

  3. Cygwin + CMake 测试

    https://www.cygwin.com/ apt-get for cygwin? wget rawgit.com/transcode-open/apt-cyg/master/apt-cyg in ...

  4. Android性能优化典范(转)

    转载自oschina. 2015年伊始,Google发布了关于Android性能优化典范的专题, 一共16个短视频,每个3-5分钟,帮助开发者创建更快更优秀的Android App.课程专题不仅仅介绍 ...

  5. java 发送http json请求

    public void getRemoteId(HttpServletRequest request,Model model){ String name = request.getParameter( ...

  6. Top 30 Nmap Command Examples For Sys/Network Admins

    Nmap is short for Network Mapper. It is an open source security tool for network exploration, securi ...

  7. vb 修改数据库

    Dim rscode As New ADODB.Recordset ................... Set RsCode = zwpub.DataMdb.DbConnect.Execute(& ...

  8. Foundation和CoreFoundation之间的转换

    Foundation是OC的东西,CoreFoundation是C语言的东西 eg: NSString\NSArray\NSDictionary 属于Foundation CFStringRef\CF ...

  9. MFC的简单加法器(二)

    创建对话框主要分两大步,第一,创建对话框资源,主要包括创建新的对话框模板.设置对话框属性和为对话框添加各种控件:第二,生成对话框类,主要包括新建对话框类.添加控件变量和控件的消息处理函数等.鸡啄米在本 ...

  10. C++经典编程题#6:分配病房

    总时间限制:  1000ms 内存限制:  65536kB 描述 某个科室的病房分为重症和普通,只有当病人的疾病严重程度超过了入住重症病房的最低严重值,才可以安排入住重症病房. 现在要求设计一个程序, ...