#include
#include
#include
#include
#include
#include
#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:执行结果