C++程序利用信号量实现程序只能启动一个
来源:互联网 发布:dell服务器数据恢复 编辑:程序博客网 时间:2024/05/16 12:01
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <dirent.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#define PRMS 0644
typedef int SEM_ID;
#define CreateSem(Key,Num) semget((Key),(Num),PRMS|IPC_CREAT)
#define OpenSem(Key) semget((Key),0,PRMS)
#define SemGetval(Semid,No) semctl((Semid),(No),GETVAL,NULL)
#define RemoveSem(Semid) semctl((Semid), 0,IPC_RMID,NULL)
SEM_ID m_Semid;
/****************************************************************
* 函数名: Check *
* 功能 : 根据信号灯判断程序是否已经启动 *
* 接口 : *
* 参数 : *
* m_Key in 信号灯 *
* 返回 : 1:成功 <> 0 程序已经运行 -1设置信号灯失败 *
*****************************************************************/
int Check(long m_Key)
{
m_Semid = OpenSem(m_Key);
if( m_Semid < 0 )
{
m_Semid = CreateSem(m_Key,1);
if( m_Semid < 0 )
return -1;
}
else
{
if(SemGetval(m_Semid,0) !=0 )
return 0;
}
return 1;
}
/****************************************************************
* 函数名: Mark *
* 功能 : 置信号灯 *
* 接口 : *
* 参数 : *
* 返回 : 0 成功; -1 失败 *
*****************************************************************/
int Mark()
{
struct sembuf Flag[2]={0,0,IPC_NOWAIT,0,1,SEM_UNDO};
if( semop(m_Semid,&Flag[0],2)<0 )
return -1;
return 0;
}
/****************************************************************
* 函数名: Unmark *
* 功能 : 释放信号量 *
* 接口 : *
* 参数 : 无 *
* 返回 : 无 *
*****************************************************************/
void Unmark()
{
if( m_Semid > -1 )
RemoveSem(m_Semid);
}
void handle()
{
fprintf(stderr,"this is handle()/n" );
}
int main(void)
{
switch(Check(1001))
{
case 0:
fprintf(stderr,"Another program with same ID is running!/n" );
exit(1);
case -1:
fprintf(stderr,"Check program ID error/n" );
exit(1);
}
int back;
setpgrp();
setsid();
signal(SIGHUP,SIG_IGN);
back = fork();
if(back == 0)
{
if(Mark() < 0)
{
fprintf(stderr,"Mark program ID error. Quit/n" );
Unmark();
exit(1);
}
for(int i=0;i<10;i++)
{
handle();
sleep(1);
}
}
else
{
fprintf(stderr,"end!/n");
}
}
环境:HP-UX fjdw2 B.11.11 U 9000/800 (tS)
编译命令:aCC -o signal signal.cpp
运行:signal
信号量函数 semget() semop() semctl()
可以使用系统调用semget()创建一个新的信号量集,或者存取一个已经存在的信号量集:
原型:intsemget(key_t key,int nsems,int semflg);
返回值:如果成功,则返回信号量集的IPC标识符。如果失败,则返回-1:errno=EACCESS(没有权限)
EEXIST(信号量集已经存在,无法创建)
EIDRM(信号量集已经删除)
ENOENT(信号量集不存在,同时没有使用IPC_CREAT)
ENOMEM(没有足够的内存创建新的信号量集)
ENOSPC(超出限制)
下面是一个打开和创建信号量集的程序:
intopen_semaphore_set(key_t keyval,int numsems)
{
intsid;
if(!numsems)
return(-1);
if((sid=semget(mykey,numsems,IPC_CREAT|0660))==-1)
{
return(-1);
}
return(sid);
}
};
系统调用:semop();
调用原型:int semop(int semid,struct sembuf*sops,unsign ednsops);
返回值:0,如果成功。-1,如果失败:errno=E2BIG(nsops大于最大的ops数目)
EACCESS(权限不够)
EAGAIN(使用了IPC_NOWAIT,但操作不能继续进行)
EFAULT(sops指向的地址无效)
EIDRM(信号量集已经删除)
EINTR(当睡眠时接收到其他信号)
EINVAL(信号量集不存在,或者semid无效)
ENOMEM(使用了SEM_UNDO,但无足够的内存创建所需的数据结构)
ERANGE(信号量值超出范围)
structsembuf{
ushortsem_num;/*semaphore index in array*/
shortsem_op;/*semaphore operation*/
shortsem_flg;/*operation flags*/
sem_num将要处理的信号量的个数。
sem_op要执行的操作。
sem_flg操作标志。
系统调用:semctl();
原型:int semctl(int semid,int semnum,int cmd,union semunarg);
返回值:如果成功,则为一个正数。
如果失败,则为-1:errno=EACCESS(权限不够)
EFAULT(arg指向的地址无效)
EIDRM(信号量集已经删除)
EINVAL(信号量集不存在,或者semid无效)
EPERM(EUID没有cmd的权利)
ERANGE(信号量值超出范围)
系统调用semctl()的第一个参数是关键字值。第二个参数是信号量数目。
·IPC_STAT读取一个信号量集的数据结构semid_ds,并将其存储在semun中的buf参数中。
·IPC_SET设置信号量集的数据结构semid_ds中的元素ipc_perm,其值取自semun中的buf参数。
·IPC_RMID将信号量集从内存中删除。
·GETALL用于读取信号量集中的所有信号量的值。
·GETNCNT返回正在等待资源的进程数目。
·GETPID返回最后一个执行semop操作的进程的PID。
·GETVAL返回信号量集中的一个单个的信号量的值。
·GETZCNT返回这在等待完全空闲的资源的进程数目。
·SETALL设置信号量集中的所有的信号量的值。
·SETVAL设置信号量集中的一个单独的信号量的值。
/*arg for semctl systemcalls.*/
unionsemun{
intval;/*value for SETVAL*/
structsemid_ds*buf;/*buffer for IPC_STAT&IPC_SET*/
ushort*array;/*array for GETALL&SETALL*/
structseminfo*__buf;/*buffer for IPC_INFO*/
void*__pad;
下面的程序返回信号量的值。当使用GETVAL命令时,调用中的最后一个参数被忽略:
{
return(semctl(sid,semnum,GETVAL,0));
}
printer_usage()
{
int x;
for(x=0;x<MAX_PRINTERS;x++)
printf("Printer%d:%d/n/r",x,get_sem_val(sid,x));
}
{
union semunsemopts;
semopts.val=initval;
semctl(sid,semnum,SETVAL,semopts);
}
- C++程序利用信号量实现程序只能启动一个
- .NET程序只能启动一个
- 使程序只能启动一个
- FileLock实现程序只能启动一次
- WinCE C#程序,控制启动时只能启动一个程序,使用互斥量来实现,该实现方法测试通过
- linux用文件锁实现保证一个程序只能启动一个进程
- Singleton 同一个程序同时只能启动一个实例
- C语言实现的一个程序只能运行一次,不能重复运行
- C#.NET客户端CS程序 只能启动一次
- 让程序只能启动一份
- 利用VC++编程实现程序自动启动
- 利用VC++编程实现程序自动启动
- 利用VC++编程实现程序自动启动
- 利用VC++编程实现程序自动启动
- c# 利用Time实现定时启动程序
- 利用注册表实现程序开机启动
- c# Winform 如何实现程序只能同时运行一个实例
- 实现程序只能运行一个实例(单例)
- 实例学习(上下级类别判断)
- Java中Set的深入研究
- 标准wince5.0 BSP之SD卡驱动分析
- VS2008 修改模板,让项目文件自动添加版权信息
- 使用Delphi解析XML 文档
- C++程序利用信号量实现程序只能启动一个
- 在WinForm应用程序中实现自动升级
- GridView 72绝技
- 网络摘抄_http状态码
- GridView内嵌checkbox的全选功能
- 几种拆焊方法
- VS中自定义模板方法
- 北大青鸟ACCP软件工程认证培训资料
- The Regulator 轻松上手