UNIX环境高级编程学习之第十五章进程间通信 - 信号量的使用(信号灯的使用, 计算信号灯)
2010-08-29 13:45
627 查看
UNIX环境高级编程学习之第十五章进程间通信 - 信号量的使用(信号灯的使用, 计算信号灯)
/* User:Lixiujie * Date:20100829 * Desc:信号量的使用(信号灯的使用, 计算信号灯) * File:semaphore.c * System:Ubuntu 64bit * gcc semaphore.c -o SemDemo */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> 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 */ //test!! void *__pad; }; /* 取当前文件路径 */ char* getCurrentFilePath(char *szCurrentFilePath){ char szBuf[256] = { 0x00 }; strcpy(szBuf, __FILE__); if (strstr(szBuf, "/") == NULL){ memset(szBuf, 0x00, sizeof(szBuf)); strcpy(szBuf, getenv("PWD")); strcat(szBuf, "/"); strcat(szBuf, __FILE__); } strcpy(szCurrentFilePath, szBuf); return szCurrentFilePath; } int main(int argc, char * argv[]){ char szFilePath[256] = { '/0' }; key_t semKey; int i; union semun arg; int semID; int tmpErrno; /* 等待信号集初始化完成尝试次数 */ int iMaxTries = 3; /* 信号集初始化完成标志 */ int iInitOk = 0; /* 当前信号集信息, 内核分配给每个信号集的结构 */ struct semid_ds semCurrInfo; /* 系统信号集限制信息 */ struct seminfo semInfo; struct sembuf semBuf; getCurrentFilePath(szFilePath); /* 产生key */ semKey = ftok(szFilePath, 1); if (-1 == semKey){ perror("main() ftok() is failed!/n"); exit(1); } /* 创建一个信号量集,只包含一个信号 */ semID = semget(semKey, 1, IPC_CREAT|IPC_EXCL|00666); if (-1 == semID){ tmpErrno = errno; if (EEXIST == tmpErrno){ perror("main() semget() is already exists!/n"); /* 获取一个信号量集,只包含一个信号 */ semID = semget(semKey, 1, IPC_CREAT|00666); if (-1 == semID){ perror("main() semget() semget() is failed!/n"); exit(1); } arg.buf = &semCurrInfo; for (i = 0;i < iMaxTries;i++){ if (semctl(semID, 0, IPC_STAT, arg) == -1){ perror("main() semget() semget() is failed!/n"); }else{ /* sem_otime:最后semop修改时间,创建初始值为0 */ if (arg.buf->sem_otime != 0){ iInitOk = 1; break; } } sleep(1); } if (0 == iInitOk){ /* 第一个创建semaphore进程没有初始化完成或刚好初始化完成, * 本次要初始化一下,否则无法下面的工作。 */ arg.val = 1;/* 资源数 */ if (semctl(semID, 0, SETVAL, arg) == -1){ perror("main() semget() semctl() is failed/n"); exit(-1); } } } else { perror("main() semget() is failed!/n"); exit(1); } }else{ arg.val = 1;/* 资源数 */ if (semctl(semID, 0, SETVAL, arg) == -1){ perror("main() semctl() is failed/n"); exit(-1); } } /* 打印当前信号集信息 */ arg.buf = &semCurrInfo; if (semctl(semID, 0, IPC_STAT, arg) == -1){ perror("main() semctl() is failed/n"); exit(-1); } printf("当前拥有用户:%d/n", arg.buf->sem_perm.uid); printf("当前拥有用户组:%d/n", arg.buf->sem_perm.gid); printf("创建用户:%d/n", arg.buf->sem_perm.cuid); printf("创建用户组:%d/n", arg.buf->sem_perm.cgid); /* 打印当前系统信号集限制信息 */ arg.__buf = &semInfo; if (semctl(semID, 0, SEM_INFO, arg) == -1){ perror("main() semctl() is failed/n"); exit(-1); } printf("the number of entries in semaphore map is %d /n", arg.__buf->semmap); printf("max number of semaphore identifiers is %d /n", arg.__buf->semmni); printf("mas number of semaphores in system is %d /n", arg.__buf->semmns); printf("the number of undo structures system wide is %d /n", arg.__buf->semmnu); printf("max number of semaphores per semid is %d /n", arg.__buf->semmsl); printf("max number of ops per semop call is %d /n", arg.__buf->semopm); printf("max number of undo entries per process is %d /n", arg.__buf->semume); printf("the sizeof of struct sem_undo is %d /n", arg.__buf->semusz); printf("the maximum semaphore value is %d /n", arg.__buf->semvmx); /* 申请使用资源 */ printf("ask for resource start./n"); semBuf.sem_num = 0; semBuf.sem_op = -1; semBuf.sem_flg = SEM_UNDO; /* 异常退出资源回收 */ if (semop(semID, &semBuf, 1) == -1){ perror("main() semop() op -1 is failed!/n"); exit(1); } printf("ask for resource complete./n"); sleep(10); /* 释放资源 */ printf("free resource start./n"); semBuf.sem_num = 0; semBuf.sem_op = 1; semBuf.sem_flg = SEM_UNDO; /* 异常退出资源回收 */ if (semop(semID, &semBuf, 1) == -1){ perror("main() semop() op 1 is failed!/n"); exit(1); } printf("free resource complete./n"); /* 显示的删除信号集 */ if (semctl(semID, 0, IPC_RMID) == -1){ perror("main() semctl() IPC_RMID is failed!/n"); }else{ printf("Remove semaphore OK!/n"); } return 0; }
相关文章推荐
- UNIX环境高级编程学习之第十五章进程间通信 - 系统V 共享内存使用(使用信号灯保护共享内存)
- UNIX环境高级编程学习之第十五章进程间通信 - 通过匿名管道实现父子进程同步
- UNIX环境高级编程学习之第十五章进程间通信 - 通过半双工匿名管道实现父子进程通信
- UNIX环境高级编程学习之第十五章进程间通信 - 通过消息队列实现进程间通信
- UNIX环境高级编程学习之第十五章进程间通信 - 两个进程通过映射普通文件实现共享内存通信
- UNIX环境高级编程学习之第十五章进程间通信 - 通过有名管道(命名管道)实现进程间通信
- UNIX环境高级编程 第十五章:进程间通信:是指在不同进程之间传播或交换信息
- UNIX环境高级编程学习之第十六章网络IPC:套接字 - 套接字选项的使用 (心跳检测、绑定地址复用)
- UNIX环境高级编程学习之第十一章线程-使用条件变量
- UNIX环境高级编程学习之第十一章线程-使用读写锁
- UNIX:高级环境编程 - 第十五章 IPC:进程间通信
- UNIX环境高级编程学习之第三章文件IO-文件读偏移操作
- UNIX环境高级编程学习笔记
- UNIX环境高级编程-第15章- 进程间通信 - 二
- UNIX环境高级编程学习之第七章进程环境-环境变量表读取/添加/修改/删除
- UNIX环境高级编程学习之第十三章守护进程 - 单实例的守护进程
- 1.UNIX环境高级编程学习环境搭建---apue.h,unix---apue.h
- UNIX环境高级编程学习之第六章系统数据文件和信息-取所有组名、GID
- <<UNIX环境高级编程>>学习总结——第二章:UNIX标准化及实现
- unix环境高级编程第三版源代码编译及使用