UNIX环境高级编程学习之第十五章进程间通信 – 信号量的使用(信号灯的使用, 计算信号灯)

Linux/Unix C/C++ xiujie 103℃ 0评论 已收录

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;
}


喜欢 (0)
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址