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