/************************************************/
/* sem_com.h */
#ifndef SEM_COM_H
#define SEM_COM_H //定義sem_com.h文件
#include <sys/ipc.h>
#include <sys/sem.h>
union semun //定義聯合體union semnn結構
{
int val;
struct semid_ds *buf;
unsigned short *array;
};
int init_sem(int, int); //函數申明
int del_sem(int);
int sem_p(int);
int sem_v(int);
#endif /* SEM_COM_H */
/*************************************************/
/* sem_com.c */
#include "sem_com.h" //引用文件sem_com.h
int init_sem(int sem_id, int init_value) //信號量初始化(賦值)函數
{
union semun sem_union;
sem_union.val = init_value; //init_value爲初始值
if (semctl(sem_id, 0, SETVAL, sem_union) == -1)
{
perror("Initialize semaphore");
return -1;
}
return 0;
}
int del_sem(int sem_id) //系統中刪除信號量的函數
{
//union semun sem_union;
//if (semctl(sem_id, 0, IPC_RMID, sem_union) == -1)
if (semctl(sem_id, 0, IPC_RMID, 0) == -1)
{
perror("Delete semaphore");
return -1;
}
}
int sem_p(int sem_id) //p操作函數
{
struct sembuf sem_b;
sem_b.sem_num = 0; /*id*/ //單個信號量的編號應該爲0
sem_b.sem_op = -1; /* P operation*/ //表示p操作
sem_b.sem_flg = SEM_UNDO; //系統自動釋放將會在系統中殘留的信號量
if (semop(sem_id, &sem_b, 1) == -1) /*1:first struct*/
{
perror("P operation");
return -1;
}
return 0;
}
int sem_v(int sem_id) //v操作函數
{
struct sembuf sem_b;
sem_b.sem_num = 0; /* id */ //單個信號量的編號應該爲0
sem_b.sem_op = 1; /* V operation */ //表示爲v操作
sem_b.sem_flg = SEM_UNDO; /* It's tracks be follow, to automatical free for it*/ //系統自動釋放將會在系統中殘留的信號量
if (semop(sem_id, &sem_b, 1) == -1)
{
perror("V operation");
return -1;
}
return 0;
}
/*****************************************************************/
/* sem_fork.c */
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define DELAY_TIME 3 //爲了突出演示效果,等待幾秒鐘
int main(void)
{
pid_t result;
int sem_id;
sem_id = semget(ftok(".", 'a'), 1, 0666|IPC_CREAT); /* create a semaphore set */ //創建一個信號量
init_sem(sem_id, 1);
/* store the child's PID in result */
result = fork(); //調用fork()函數 創建子進程
if(result == -1)
perror("fork failed");
else if(result == 0){ /* child */ //返回值爲0代表子進程
sem_p(sem_id); //p操作
/*** enter critical section ***/
fprintf(stdout, "Child process will wait for some seconds.../n");
sleep(DELAY_TIME);
fprintf(stdout, "The returned value is %d"
" in the child process(PID = %d)/n", result, getpid());
/*** leave critical section ***/
sem_v(sem_id); //v操作
}
else if(result > 0){ /* parent */ //返回值大於0代表父進程
sem_p(sem_id); //p操作
/*** enter critical section ***/
fprintf(stdout, "The returned value is %d"
" in the father process(PID = %d)/n", result, getpid());
/*** leave critical section ***/
sem_v(sem_id); //v操作
/*** delete the semaphore ***/
wait(NULL);
del_sem(sem_id);
}
exit(0);
}
/**************************************************************/