本文已参与「新人创作礼」活动,一起开启掘金创作之路。
Linux信号量编程
信号量编程的一个小应用
代码如下:
#include<stdio.h>
#include<sys/sem.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<unistd.h>
union semun{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
void pGetKey(int id)
{
struct sembuf set;
set.sem_num = 0;//
set.sem_op = -1;
set.sem_flg = SEM_UNDO;
semop(id,&set,1);
printf("getKEY\n");
}
void vPutBack(int id)
{
struct sembuf set;
set.sem_num = 0;
set.sem_op = 1;
set.sem_flg = SEM_UNDO;
semop(id,&set,1);
printf("Put back Key\n");
}
int main(int argc,char **argv)
{
key_t key;
int semid;
key = ftok(".",2);
semid = semget(key,1,IPC_CREAT|0666);//获取/创建信号量
union semun initsem;
initsem.val = 0;//锁
semctl(semid,0,SETVAL,initsem);//初始化信号量
int pid = fork();
if(pid > 0){
//去拿锁
pGetKey(semid);//拿钥匙
printf("This is father\n");
vPutBack(semid);//放钥匙
semctl(semid,0,IPC_RMID);
}else if(pid == 0){
printf("This is child\n");
vPutBack(semid);
}else{
printf("create error\n");
}
return 0;
}
通过上边的代码运行后,就能确保子进程比父进程先运行,通过信号量来控制。
函数原型:
NAME
semop, semtimedop - System V semaphore operations
SYNOPSIS
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semop(int semid, struct sembuf *sops, size_t nsops);
int semtimedop(int semid, struct sembuf *sops, size_t nsops,
const struct timespec *timeout);
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
semtimedop(): _GNU_SOURCE
DESCRIPTION
Each semaphore in a System V semaphore set has the following associated values:
unsigned short semval; /* semaphore value */
unsigned short semzcnt; /* # waiting for zero */
unsigned short semncnt; /* # waiting for increase */
pid_t sempid; /* PID of process that last
semop() performs operations on selected semaphores in the set indicated by semid. Each of the nsops elements in the array pointed to by sops is a structure that specifies an operation to be performed on a single semaphore. The elements of this structure are of type struct sembuf, containing the following members:
unsigned short sem_num; /* semaphore number */
short sem_op; /* semaphore operation */
short sem_flg; /* operation flags */
Flags recognized in sem_flg are IPC_NOWAIT and SEM_UNDO. If an operation specifies SEM_UNDO, it will be automatically undone when the process terminates.
NAME
semctl - System V semaphore control operations
SYNOPSIS
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semctl(int semid, int semnum, int cmd, ...);
DESCRIPTION
semctl() performs the control operation specified by cmd on the System V semaphore set identified by semid, or on the semnum-th semaphore of that set. (The semaphores in a set are numbered starting at 0.)
This function has three or four arguments, depending on cmd. When there are four, the
fourth has the type union semun. The calling program must define this union as follows:
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux-specific) */
};
The semid_ds data structure is defined in <sys/sem.h> as follows:
struct semid_ds {
struct ipc_perm sem_perm; /* Ownership and permissions */
time_t sem_otime; /* Last semop time */
time_t sem_ctime; /* Last change time */
unsigned long sem_nsems; /* No. of semaphores in set */
};
运行结果: