int val由SETVAL使用, semctl將會把arg.val設置到信號量的semval中.
struct semid_ds *buf由IPC_STAT和IPC_SET使用, 讀取時將信號量集合的semid_ds讀取到arg.buf中. 設置時使用arg.buf的三項內容.
unsigned short *array由GETALL和SETALL使用, 將讀取和設置集合中的所有信號量
IPC_STAT讀取一個信號量集的數據結構semid_ds,並將其存儲在semun中的buf參數中。
IPC_SET設置信號量集的數據結構semid_ds中的元素ipc_perm,其值取自semun中的buf參數。
IPC_RMID將信號量集從內存中刪除。
GETALL用於讀取信號量集中的所有信號量的值。
GETNCNT返回正在等待資源的進程數目。
GETPID返回最後一個執行semop操作的進程的PID。
GETVAL返回信號量集中的一個單個的信號量的值。
GETZCNT返回這在等待完全空閒的資源的進程數目。
SETALL設置信號量集中的所有的信號量的值。
SETVAL設置信號量集中的一個單獨的信號量的值。
返回值:如果成功,則爲一個正數
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sem.h>
#include <fcntl.h>
union semun{
int val;
struct semid_ds *buf;
unsigned short *arry;
};
static int sem_id = 0;
static int init_sem();
static void del_sem();
static int sem_P();
static int sem_V();
int main(int argc, char** argv)
{
char show = 'X';
int i = 0;
sem_id = semget((key_t)1234,1,0666 | IPC_CREAT);
if(argc > 1)
{
if(!init_sem())
{
printf("init failed\n");
return -1;
}
show = argv[1][0];
sleep(2);
}
for (i = 0; i< 10; i++)
{
if (!sem_P())
exit(-1);
printf("%c", show);
fflush(stdout); sleep(rand()%3);
printf("%c", show);
fflush(stdout);
if (!sem_V())
exit(-1);
if(argc >1)
{
sleep(3);
}
else
{
sleep(2);
}
}
printf("\n%d finished \n",getpid());
if (argc > 1)
{
sleep(10);
del_sem();
}
exit(0);
}
static int init_sem()
{
union semun union_sem;
union_sem.val = 1;
if (semctl(sem_id, 0, SETVAL, union_sem) == -1)
return 0;
return 1;
}
static void del_sem()
{
union semun union_sem;
if (semctl(sem_id, 0, IPC_RMID, union_sem) == -1)
printf("delete failed\n ");
}
static int sem_P()
{
struct sembuf sem;
sem.sem_num = 0;
sem.sem_op = -1;
sem.sem_flg = SEM_UNDO;
if (semop(sem_id, &sem, 1) == -1)
{
printf("sem_P failed\n");
return 0;
}
return 1;
}
static int sem_V()
{
struct sembuf sem;
sem.sem_num = 0;
sem.sem_op = 1;
sem.sem_flg = SEM_UNDO;
if (semop(sem_id, &sem, 1) == -1)
{
printf("sem_V failed\n");
return 0;
}
return 1;
}
gcc sem.c -o sem