在UNIX系统V中,一个或多个信号量构成一个信号量集合。使用信号量机制用来实现进程之间的同步和互斥,允许并发进程一次对一组信号量进行相同或不同的操作。每个P\V操作不限于减一或加一,而是可以加减任何整数,在进程终止时,系统可根据需要自动消除所有被进程操作过的信号量的影响。
关于信号量机制的数据结构、操作函数等基础知识请自行Google.下面给出一个信号量的使用实例
功能:用于进程互斥共享文件的信号量的使用
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <linux/sem.h>
#define NUM_PROCS 5
#define SEM_ID 250
#define FILE_NAME "/tmp/sem_MUTEX"
#define DELAY 400000
//各子进程互斥写文件的通用函数
void update_file(int sem_set_id,char *file_name_path,int number)
{
struct sembuf sem_op;
FILE *file;
//相当于执行P操作,申请写文件
sem_op.sem_num = 0;
sem_op.sem_op = -1;
sem_op.sem_flg = 0;
semop(sem_set_id,&sem_op,1);
//向文件写,写入的数据是进程的标识
file = fopen(file_name_path,"w");
if(file)
{
fprintf(file,"%d\n",number);
printf("%d\n",number);
fclose(file);
}
//相当于执行V操作,释放文件的使用权
sem_op.sem_num = 0;
sem_op.sem_op = 1;
sem_op.sem_flg = 0;
semop(sem_set_id,&sem_op,1);
}
//子进程准备写文件的通用函数
void do_child_loop(int sem_set_id,char *file_name)
{
pid_t pid = getpid();//得到本进程的标识
int i;
int j;
for(i = 0; i < 3; i++)
{
update_file(sem_set_id,file_name,pid);
for(j = 0; j < 200000; j++);//暂停一段时间
}
}
int main(int argc,char * *argv)
{
int sem_set_id;
int child_pid;
union semun sem_val;
int i;
int rc;
//创建一个信号量集合,标识为255,只有一个信号量
sem_set_id = semget(SEM_ID,1,IPC_CREAT|0600);
if(sem_set_id == -1)
{
perror("main's semget error ");
exit(1);
}
//把该信号量的值设置为1
sem_val.val = 1;
rc = semctl(sem_set_id,0,SETVAL,sem_val);
if(rc == -1)
{
perror("mian:setctl");
exit(1);
}
//建立一些子进程,以便竞争并互斥地向文件写
for(i = 0; i <NUM_PROCS; i++)
{
child_pid = vfork();这里将fork改成vfork
switch(child_pid)
{
case -1:
perror("fork()");
exit(1);
case 0:
do_child_loop(sem_set_id,FILE_NAME);
exit(0);
default:break;
}
}//创建子进程的循环结束
//父进程等待子进程结束
for(i = 0; i < 10; i++)
{
int child_status;
wait(&child_status);
}
printf("main is done\n");
fflush(stdout);
return 0;
}