www.pudn.com > pthread_examples.rar > semop.c


#include  
#include  
#include  
 
#define SEM_PATH "/home/share/jinbq/pthread_examples/semop/my_sem" 
#define max_tries 3  
 
int semid; 
 
main() 
{ 
	int flag1, flag2, key, i, init_ok, tmperrno; 
	struct semid_ds sem_info; 
	struct seminfo sem_info2; 
 
/* 
	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; 
	}; 
 
*/ 
	 
	union semun arg; 			//union semun: 请参考附录2 
	struct sembuf askfor_res, free_res; 
	flag1 = IPC_CREAT|IPC_EXCL|00666; 
	flag2 = IPC_CREAT|00666; 
	key = ftok(SEM_PATH, 'a'); 
	//error handling for ftok here; 
	init_ok = 0; 
	 
	semid = semget(key, 1, flag1);//create a semaphore set that only includes one semphore. 
	if(semid < 0) 
	{ 
		tmperrno = errno; 
		perror("semget"); 
		 
		if(tmperrno == EEXIST) 
		//errno is undefined after a successful library call( including perror call) so it is saved //in tmperrno. 
		{ 
			semid = semget(key, 1, flag2); 
			//flag2 只包含了IPC_CREAT标志, 参数nsems(这里为1)必须与原来的信号灯数目一致 
			arg.buf = &sem_info; 
			for(i=0; isem_otime!=0){ i=max_tries;  init_ok=1;} 
					else	 sleep(1);	 
				} 
			} 
			if(!init_ok) 
	  // do some initializing, here we assume that the first process that creates the sem will  
	  // finish initialize the sem and run semop in max_tries*1 seconds. else it will not run  
	  // semop any more. 
			{ 
				arg.val=1; 
				if(semctl(semid,0,SETVAL,arg)==-1) perror("semctl setval error"); 
			}  
		} 
		else 
		{perror("semget error, process exit");	exit();	} 
	} 
	else //semid>=0; do some initializing 	 
	{ 
		arg.val=1; 
		if(semctl(semid,0,SETVAL,arg)==-1) 
			perror("semctl setval error"); 
	} 
	//get some information about the semaphore and the limit of semaphore in redhat8.0 
		arg.buf=&sem_info; 
		if(semctl(semid, 0, IPC_STAT, arg)==-1) 
			perror("semctl IPC STAT");		 
		printf("owner's uid is %d\n", 	arg.buf->sem_perm.uid); 
		printf("owner's gid is %d\n", 	arg.buf->sem_perm.gid); 
		printf("creater's uid is %d\n", 	arg.buf->sem_perm.cuid); 
		printf("creater's gid is %d\n", 	arg.buf->sem_perm.cgid); 
 
		arg.__buf=&sem_info2; 
		if(semctl(semid,0,IPC_INFO,arg)==-1) 
			perror("semctl IPC_INFO"); 
		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); 
		 
	//now ask for available resource:	 
		askfor_res.sem_num=0; 
		askfor_res.sem_op=-1; 
		askfor_res.sem_flg=SEM_UNDO;		 
			 
			if(semop(semid,&askfor_res,1)==-1)//ask for resource 
				perror("semop error"); 
		 
		sleep(3); //do some handling on the sharing resource here, just sleep on it 3 seconds 
		printf("now free the resource\n");	 
		 
	//now free resource	 
		free_res.sem_num=0; 
		free_res.sem_op=1; 
		free_res.sem_flg=SEM_UNDO; 
 
		if(semop(semid,&free_res,1)==-1)//free the resource. 
			if(errno==EIDRM) 
				printf("the semaphore set was removed\n"); 
	//you can comment out the codes below to compile a different version:			 
		if(semctl(semid, 0, IPC_RMID)==-1) 
			perror("semctl IPC_RMID"); 
		else printf("remove sem ok\n"); 
}