linux信号量的SEM_UNDO参数

信号量是不同进程间或一个给定进程内部不同线程间同步的机制。System V信号量是一个或多个信号量的集合,其中的每一个都是氮素的计数信号量。System V信号量由内核维护,主要函数有:semget,semop,semctl。

我们重点来讨论semop函数,该函数的主要功能是对信号进行PV操作。

P操作负责把当前进程由运行状态转换为阻塞状态,知道另外一个进程唤醒它。操作为:申请一个空闲资源(把信号量减1),若成功,则退出,若失败,则该进程被阻塞。

V操作负责把被阻塞的进程唤醒,它有一个参数表,存放着等待被唤醒的进程信息,操作为:释放一个被占用的资源(把信号量加1),如果发现有被阻塞的进程,则选择一个唤醒。

semop函数原型:

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

semop操作中:sembuf结构的sem_flg成员可以为0,IPC_NOWAIT,SEM_UNDO,为SEM_UNDO时,它将使操作系统跟踪当前进程对这个信号量的修改情况,如果这个进程在没有释放该信号量的情况下终止,操作系统将自动释放该进程持有的信号量。

下面我们用一段程序来看看SEM_UNDO的作用:

#include "comm.c"文件:

static int comm_creat_sem_set(int _sem_nums,int flag)

{

key_t _key=ftok(_PATH_,_PROJ_ID_);

if(_key<0)

{

perror("ftok");

return -1;

}

int sem_id=semget(_key,_sem_nums,flag);

if(sem_id<0)

{

return -1;

}

return sem_id;

}

int creat_sem_set(int _sem_nums)

{

umask(0);

int flag=IPC_CREAT|IPC_EXCL|0666;

return comm_creat_sem_set(_sem_nums,flag);

}

int get_sem_set(int _sem_nums)

{

int flag=IPC_CREAT;

return comm_creat_sem_set(_sem_nums,flag);

}

int init_sem_set(int _sem_id,int _sem_num,int _init_val)

{

union semun _un;

_un.val=_init_val;

if(semctl(_sem_id,_sem_num,SETVAL,_un)<0)

{

perror("semctl");

return -1;

}

return 0;

}

int p_sem(int _sem_id,int _seq_num)

{

struct sembuf _sem_buf[1];

_sem_buf[0].sem_num=_seq_num;

_sem_buf[0].sem_op=-1;

//  _sem_buf[0].sem_flg=SEM_UNDO;

_sem_buf[0].sem_flg=0;

if(semop(_sem_id,_sem_buf,1)<0)

{

perror("semop");

return -1;

}

return 0;

}

int v_sem(int _sem_id,int _seq_num)

{

struct sembuf _sem_buf[1];

_sem_buf[0].sem_num=_seq_num;

_sem_buf[0].sem_op=1;

_sem_buf[0].sem_flg=0;

//  _sem_buf[0].sem_flg=SEM_UNDO;

if(semop(_sem_id,_sem_buf,1)<0)

{

perror("semop");

return -1;

}

return 0;

}

comm.h文件:

#pragma once

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/sem.h>

#define _PATH_ "."

#define _PROJ_ID_ 0x6666

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

};

int creat_sem_set(int _sem_nums);

int get_sem_set(int _sem_nums);

int init_sem_set(int _sem_id,int _sem_nums,int _init_val);

int p_sem(int _sem_id,int _seq_num);

int v_sem(int _sem_id,int _seq_num);

int destroy_sem_set(int _sem_id);

sem.c文件:

int main()

{

int sem_id=creat_sem_set(1);

init_sem_set(sem_id,0,1);

pid_t id=fork();

if(id <0)

{

perror("fork");

exit(1);

}

else if(id==0)

{

int childid=getpid();

int fatherid=getppid();

printf("childid:%d,fatherid:%d\n",childid,fatherid);

int sem_id=get_sem_set(0);

while(1)

{

p_sem(sem_id,0);

printf("child wrinting\n");

sleep(1);

fflush(stdout);

printf("child finish post\n");

sleep(10);

fflush(stdout);

v_sem(sem_id,0);

}

}

else

{

while(1)

{

p_sem(sem_id,0);

printf("father wrinting\n");

sleep(1);

fflush(stdout);

printf("father finish post\n");

sleep(1);

fflush(stdout);

v_sem(sem_id,0);

}

}

destroy_sem_set(sem_id);

return 0;

}

在没用SEM_UNDO参数前,运行结果:

从代码中我们看到,在子进程P操作之后,我们让子进程sleep了10秒,在这之前我们把子进程傻掉了,也就是子进程没有进行V操作,所以没有释放占用的信号量,我们会看到,把子进程杀掉之后,父进程阻塞了。

而我们用了SEM_UNDO这个参数后,运行结果如下:

我们可以看到,在把子进程kill后,父进程照样可以运行,因为使用了SEM_UNDO后,操作系统自动释放该进程持有的信号量,从而可以使得另一个进程可以继续工作。否则,另外一个进程将永远阻塞。

时间: 2024-10-13 23:29:22

linux信号量的SEM_UNDO参数的相关文章

关于linux信号量的SEM_UNDO标志(防止死锁)

AT&T的贝尔实验室,对Unix早期的进程间通信进行了改进和扩充,形成了"system V IPC",其通信进程主要局限在单个计算机内.IPC对象指的是共享内存(share memory).消息队列(message queue)和信号灯集(semaphore). 信号灯(semaphore),也叫信号量.它是不同进程间或一个给定进程内部不同线程间同步的机制.System V的信号灯是一个或者多个信号灯的一个集合.其中的每一个都是单独的计数信号灯.System V 信号灯由内核维

Linux信号量详解

1.什么是信号量信号量是一种特殊的变量,访问具有原子性.只允许对它进行两个操作:1)等待信号量当信号量值为0时,程序等待:当信号量值大于0时,信号量减1,程序继续运行.2)发送信号量将信号量值加1. 我们使用信号量,来解决进程或线程间共享资源引发的同步问题. 2.Linux中信号量的使用Linux提供了一组信号量API,声明在头文件sys/sem.h中.1)semget函数:新建信号量 int semget(key_t key,int num_sems,int sem_flags); key:信

Linux 信号量 生产者消费者小例题 (嘘,我是菜鸟~)

菜鸟偶遇信号量,擦出火花(只有不熟才会有火花).于是上网搜资料和看<Unix环境高级编程>实现了几个小例题,高手请勿喷!这几位写得非常好啊: 题目来源: http://www.it165.net/os/html/201312/7039.html 信号量及其用法:http://www.cnblogs.com/hjslovewcl/archive/2011/03/03/2314341.html Mutex与Semaphore区别著名的厕所理论:http://koti.mbnet.fi/niclas

Linux信号量

sem_init的应用 (1)信号量用sem_init函数创建的,下面是它的说明: #include<semaphore.h> int sem_init (sem_t *sem, int pshared, unsigned int value); 这个函数的作用是对由sem指定的信号量进行初始化,设置好它的共享选项,并指定一个整数类型的初始值.pshared参数控制着信号量的类型.如果 pshared的值是0,就表示它是当前进程的局部信号量或者说为线程的共享信号量:否则,其它进程就能够共享这个

mysqladmin在SuSE linux系统中--sleep参数使用不准确问题

我们都知道,在MySQL中,可以使用mysqladmin命令的extended-status选项来查看MySQL的运行状态,比如获取我们常常关注的几个值: # mysqladmin -uroot -proot ext |grep "Questions\|Queries\|Innodb_rows\|Com_select \|Com_insert \|Com_update \|Com_delete " | Com_delete                               |

linux信号量之进程间同步

概念 linux信号量:允许多个线程同时进入临界区,可以用于进程间的同步. 和互斥锁(mutex)的区别:互斥锁只允许一个线程进入临界区. 所在头文件:semaphore.h 主要函数 初始化函数 int sem_init(sem_t *sem, int pshared, unsigned int value) sem:要初始化的信号量 pshared:此信号量是在进程间共享还是线程间共享 value:信号量的初始值 删除函数 int sem_destroy(sem_t *sem) sem:要销

高并发情况下Linux系统及kernel参数优化

众所周知在默认参数情况下Linux对高并发支持并不好,主要受限于单进程最大打开文件数限制.内核TCP参数方面和IO事件分配机制等.下面就从几方面来调整使Linux系统能够支持高并发环境. Iptables相关 如非必须,关掉或卸载iptables防火墙,并阻止kernel加载iptables模块.这些模块会影响并发性能. 单进程最大打开文件数限制 一般的发行版,限制单进程最大可以打开1024个文件,这是远远不能满足高并发需求的,调整过程如下: 在#号提示符下敲入: # ulimit–n 6553

嵌入式Linux启动时网络参数配置

明白了嵌入式Linux启动时网络参数配置的流程,就会对网络这一部分了然于胸,以后出现网络不通的情况,就有了解决问题的思路. 1.网络参数配置的入口: /etc/init.d/rcS,如下两行 # 配置换回lo地址 /sbin/ifconfig lo 127.0.0.1 # 配置以太网eth0地址 /etc/init.d/ifconfig-eth0 2.进入ifconfig-eth0文件: #!/bin/sh echo -n Try to bring eth0 interface up......

linux TOP命令各参数详解【转载】

实时监控或查看系统资源使用情况的工具——TOP top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器. 下面详细介绍它的使用方法: (实时监控系统资源使用情况图) 统计信息区前五行是系统整体的统计信息: 第一行是任务队列信息,同 uptime  命令的执行结果.其内容如下: 01:06:48 当前时间 up 1:22 系统运行时间,格式为时:分 1 user 当前登录用户数 load average: 0.06, 0.60, 0.