1. 程式人生 > >C語言訊號量的基本操作

C語言訊號量的基本操作

/*
*對訊號量的操作
*1.初始化
*2.申請
*3.釋放
*4.銷燬
*/

/*=============================相關函式===========================
	key_t ftok(const char *pathname, int proj_id);
	int semget(key_t key, int nsems, int semflg);
	int semctl(int semid, int semnum, int cmd, ...);
	int semop(int semid, struct sembuf *sops, unsigned nsops);
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <error.h>
#include <stdlib.h>

int sem_id=-1;		//建立訊號量集的返回值,成功返回ID,失敗返回-1
int semheld=0;

void menu();
void creat_sem();	//建立訊號量集
void init_sem();	//初始化資源
void request_res();	//申請資源
void release_res();	//釋放資源
void sem_delete();	//銷燬訊號量集

int main(int argc,char **argv)
{
	atexit(&sem_delete);
	char get[3];int select;
	menu();
	do
	{		
		printf("=====>>");
		scanf("%s",get);
		select=atoi(get);
		switch(select)
		{
			case 1:creat_sem();
				break;
			case 2:init_sem();
				break;
			case 3:request_res();
				break;
			case 4:release_res();
				break;
			case 5:return;
				break;
			default :exit(1);
		}	
	}while(1);
	return 0;
}
void menu()
{
	puts("\t\t1.建立訊號量集");
	puts("\t\t2.初始化資源");
	puts("\t\t3.申請資源");
	puts("\t\t4.釋放資源");
	puts("\t\t5.返回");
	puts("\t\t6.退出");
}
int get_key()
{
	int key=ftok(".",'c');//獲得IPC關鍵字
	return key;
}
void creat_sem()
{
	key_t key=get_key();
	sem_id=semget(key,1,IPC_CREAT|0600);//建立訊號量集
	//sem_id=semget(IPC_PRIVATE,1,IPC_CREAT|IPC_EXCL);
							//建立訊號量集(採用系統指定鍵值)
	if(sem_id==-1)
	{
		perror("creat semaphore error");
		exit(1);
	}
	printf("\t\t建立成功\n");
}
void init_sem()
{
	int val;
	int nsem_id;
	printf("\t\t初始化的訊號量索引:\t");	//選擇訊號量集中的訊號
	scanf("%d",&nsem_id);
	printf("\t\t輸入資源個數:\t");					//初始化訊號量的值
	scanf("%d",&val);
	if(semctl(sem_id,nsem_id,SETVAL,val)==-1)
	{
		printf("\t\t初始化失敗\n");
	}
	else
	printf("\t\t初始化成功,分配資源數%d\n",val);
}

void request_res()
{
	int i=0;
	printf("\t\t申請資源\n");
	struct sembuf sbuf;
	sbuf.sem_num=0;
	sbuf.sem_op=-1;
	sbuf.sem_flg=IPC_NOWAIT;
	do
	{
		if(semop(sem_id,&sbuf,1)==-1)
		{
			printf("\t\t當前沒有資源可申請\n");
			semheld=i;
			printf("\t\t擁有資源數量--->%d\n",semheld);
			return;
		}
		printf("\t\t申請----->%d\n",++i);
	}while(1);	
	return;
}

void release_res()
{
	int i=0;
	if(semheld<1)
	{
		printf("\t\t沒有任何資源可以釋放\n");
		return;
	}
	struct sembuf sbuf;
	sbuf.sem_num=0;
	sbuf.sem_op=1;
	sbuf.sem_flg=IPC_NOWAIT;
	if(semop(sem_id,&sbuf,1)==-1)
	{
		perror("semop release error");
		exit(1);
	}
	printf("\t\t釋放資源----->剩餘資源%d\n",--semheld);
	return;
}

void sem_delete()
{
	printf("\t\t刪除訊號量集\n");
	if(semctl(sem_id,0,IPC_RMID,0)==-1)
	{
		perror("release semaphore error");
	}
}