信号量机制

在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;
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值