linux 进程间通信--systemV 信号量 实例

1:代码

#include <stdio.h>
#include <sys/types.h>
#include <sys/sem.h>
#include <errno.h>
#include <stdlib.h>
#include <signal.h>
#define MAX_SEMAPHORES  3
union semun
{
        int val;                   			/* value for SETVAL */
        struct semid_ds *buf;       		/* buffer for IPC_STAT, IPC_SET */
        unsigned short int *array;  		/* array for GETALL, SETALL */
        struct seminfo *__buf;      		/* buffer for IPC_INFO */
};
static int set_semvalue(int sem_id,int semIndex,int semValue)
{
    union semun sem_union;
	int value;
    sem_union.val = semValue;
    if (semctl(sem_id, semIndex, SETVAL, sem_union) == -1)
    {
    	return(0);
    }
	printf("set value success,");
	printf("init value is %d\n",get_semvalue(sem_id,semIndex));
	return(1);
}

int get_semvalue(int sem_id,int semIndex)
{
	int res;
	if((res=semctl(sem_id, semIndex, GETVAL)) == -1)
	{
		perror("semctl");
		exit(EXIT_FAILURE);
	}
	return res;
}

static int semaphore_v(int sem_id,int semIndex)
{
	struct sembuf sem_b;

	sem_b.sem_num = semIndex;
	sem_b.sem_op = 1; /* V() */
	//sem_b.sem_flg = SEM_UNDO;
	sem_b.sem_flg=IPC_NOWAIT; //0
	if (semop(sem_id, &sem_b, 1) == -1)
	{
		perror("semop");
		return(0);
	}
	return(1);
}

static int semaphore_p(int sem_id,int semIndex)
{
	struct sembuf sem_b;
	sem_b.sem_num = semIndex;
	sem_b.sem_op = -1; /* V() */
	//sem_b.sem_flg = SEM_UNDO;
	sem_b.sem_flg=IPC_NOWAIT;//0
	if (semop(sem_id, &sem_b, 1) == -1)
	{
		perror("semop");
		return(0);
	}
	return(1);
}
void signalHandler(int sig)
{
	printf("child process exit\n");
	exit(EXIT_SUCCESS);
}
void semphorePV()
{
	pid_t childPid;
	int i;
	int value;
    key_t key;
	int status;
	int chlid_sem_id,parent_sem_id,semIndex=0,semValue=MAX_SEMAPHORES;
	if((childPid=fork())==-1)
	{
		perror("fork");
		exit(EXIT_FAILURE);
	}
	else if(childPid==0)
	{
#if 1
	struct sigaction sa;
	sa.sa_handler = signalHandler;
	sa.sa_flags = 0;	/* Interrupt system calls */
	sigemptyset(&sa.sa_mask);
	sigaction(SIGINT, &sa, NULL);
	sigaction(SIGQUIT, &sa, NULL);
#endif
		if((chlid_sem_id=semget((key_t)123456,1,IPC_CREAT|0770))==-1)
		{
			perror("semget");
			exit(EXIT_FAILURE);
		}
		if (!set_semvalue(chlid_sem_id,semIndex,semValue))
		{
			fprintf(stderr, "Failed to initialize semaphore\n");
			exit(EXIT_FAILURE);
		}
		value=get_semvalue(chlid_sem_id,semIndex);
		printf("this is child,the current value is %d\n",value);
		if(!semaphore_v(chlid_sem_id,semIndex))
		{
			fprintf(stderr, "Failed to v operator\n");
			exit(EXIT_FAILURE);
		}
		value=get_semvalue(chlid_sem_id,semIndex);
		printf("child V operator,the current value is %d\n",value);
		printf("--------------------------------------------------\n");
		while(1)
		{
			if(!semaphore_v(chlid_sem_id,semIndex))
			{
				fprintf(stderr, "Failed to v operator\n");
				exit(EXIT_FAILURE);
			}
			value=get_semvalue(chlid_sem_id,semIndex);
			printf("child V operator,the current value is %d\n",value);
			sleep(2);
		}
		printf("child exit success\n");
		exit(EXIT_SUCCESS);
	}
	else	//parent
	{
		sleep(1);
		if((parent_sem_id=semget((key_t)123456,1,IPC_CREAT|0770))==-1)
		{
			perror("semget");
			exit(EXIT_FAILURE);
		}
		value=get_semvalue(parent_sem_id,semIndex);
		printf("this is parent ,the current value is %d\n",value);
		sleep(1);
		if(!semaphore_p(parent_sem_id,semIndex))
		{
			fprintf(stderr, "Failed to v operator\n");
			exit(EXIT_FAILURE);
		}
		printf("parent P operator,the current value is %d\n",value);
		printf("################################################################\n");
		while(1)
		{
			if(!semaphore_p(parent_sem_id,semIndex))
			{
				fprintf(stderr, "Failed to v operator\n");
				break;
			}
			else
			{
				value=get_semvalue(parent_sem_id,semIndex);
				printf("parent P operator,the current value is %d\n",value);
			}
			sleep(1);
		}
		kill(childPid,SIGINT);
		sleep(2);
		if(semctl(parent_sem_id,0, IPC_RMID,(struct msquid_ds*)0)==-1)
		{
			perror("semctl");
			exit(EXIT_FAILURE);
		}
		else
		{
			printf("the parent remove the sem\n");
		}
		return 0;
	}
}
int main(int argc,char *argv)
{
	semFunTest(argc,argv);
	semphorePV();
}



 int semFunTest(int argc,char *argv[])
 {
    int i, ret, semid;
    unsigned short sem_write_array[MAX_SEMAPHORES];
    unsigned short sem_read_array[MAX_SEMAPHORES];
    union semun arg;

    if((semid = semget( IPC_PRIVATE, MAX_SEMAPHORES,IPC_CREAT | 0666 )) == -1)
	{
		perror("semget");
		exit(EXIT_FAILURE);
	}
      /* Initialize the sem_array */
	for (i = 0 ; i < MAX_SEMAPHORES ; i++ )
	{
	  sem_write_array[i] = (unsigned short)(i+1);
	}
      /* Update the arg union with the sem_array address */
     arg.array = sem_write_array;
      /* Set the values of the semaphore-array */
     if((ret = semctl( semid, 0, SETALL, arg)) == -1)
  	 {
  	  	 perror("SETALL failed\n");
  	 }
   	/* Update the arg union with another array for read */
   	arg.array = sem_read_array;
   		/* Read the values of the semaphore array */
    if((ret = semctl( semid, 0, GETALL, arg)) == -1)
	{
		printf("GETALL failed (%d)\n", errno);
	}
   /* print the sem_read_array */
	for ( i = 0 ; i < MAX_SEMAPHORES ; i++ )
	{
		printf("Semaphore %d, value %d\n", i, sem_read_array[i] );
	}
	printf("************************************************\n");
   /* Use GETVAL in a similar manner */
   for ( i = 0 ; i < MAX_SEMAPHORES ; i++ )
   {
     ret = semctl( semid, i, GETVAL );
     printf("Semaphore %d, value %d\n", i, ret );
   }
   /* Delete the semaphore */
	if(semctl(semid,0, IPC_RMID,(struct msquid_ds*)0)==-1)
	{
		perror("semctl");
		exit(EXIT_FAILURE);
	}
	else
	{
		printf("remove the sem\n");
	}
 return 0;
}


2:执行结果




代码:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

家有工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值