semExample.c(linux下信号量使用实例)

/*
 *Author:
 *Filename: semExample.h
 *Description: 提供信号量的函数调用接口
 */
#ifndef SEMEXAMPLE_H
#define SEMEXAMPLE_H




#include <sys/types.h>
#include <sys/sem.h>
#include <sys/ipc.h>

union semun {
    int              val;              /*for SETVAL*/
    struct semid_ds   *buf;            /*for IPC_STAT and IPC_SET*/
    unsigned short    *array;          /*for GETALL and SETALL*/
};



/*
 *Name: init_sem()
 *Function: 信号量的初始化
 *Arguement: 第一个参数为信号量的标志符,第二个参数为初始值
 *Returnvalue:  出错返回-1,成功返回0.
 */


int init_sem(int sem_mid,int init_value);


/*
 *Name: delete_sem()
 *Function: 信号量的删除
 *Arguement: 参数为信号量的标志符
 *Returnvalue:  出错返回-1,成功返回0.
 */


int delete_sem(int sem_mid);



/*
 *Name: voperation_sem()
 *Function: 信号量的v操作,使信号量的值加1
 *Arguement: 参数为信号量的标志符
 *Returnvalue:  出错返回-1,成功返回0.
 */


int voperation_sem(int sem_mid);




/*
 *Name: poperation_sem()
 *Function: 信号量的p操作,使信号量的值减1,该部分代码与信号量的v操作代码类似
 *Arguement: 参数为信号量的标志符
 *Returnvalue:  出错返回-1,成功返回0.
 */


int poperation_sem(int sem_mid);


#endif




/********************************************************************************************************************************************************************/

/*
 *Author:
 *Filename: semExample.c
 *Description: 因为信号量的函数调用接口负责,所以通常将信号量的函数封装成一些额基本函数供调用。
 */


#include "semExample.h"


/*
 *Name: init_sem()
 *Function: 信号量的初始化
 *Arguement: 第一个参数为信号量的标志符,第二个参数为初始值
 *Returnvalue:  出错返回-1,成功返回0.
 */


int init_sem(int sem_mid,int init_value)
{
//使用semctl函数来为信号量进行初始化
union semun sem_union;
/*
union semun
    {
        int val;//使用SETVAL的值
        struct semid_ds *buf;    //使用IPC_STAT,IPC_SET的buf
        unisgned short *array;    //使用GETALL,SETALL的数组
    }
*/


sem_union.val = init_value;
if(semctl(sem_mid,0,SETVAL,sem_union) == -1)
{
perror("Init_sem error");
return -1;
}
return 0;
}






/*
 *Name: delete_sem()
 *Function: 信号量的删除
 *Arguement: 参数为信号量的标志符
 *Returnvalue:  出错返回-1,成功返回0.
 */


int delete_sem(int sem_mid)
{
//使用sem_ct函数,命令参数设为IPC_RMID
union semun sem_union;
if(semctl(sem_mid,0,IPC_RMID,sem_union) == -1)
{
perror("Delete_sem error");
return -1;
}
return 0;
}




/*
 *Name: voperation_sem()
 *Function: 信号量的v操作,使信号量的值加1
 *Arguement: 参数为信号量的标志符
 *Returnvalue:  出错返回-1,成功返回0.
 */


int voperation_sem(int sem_mid)
{
/*调用semop函数:int semop(int semid, struct sembuf *sops, unsigned nsops);
struct sembuf
{
        unsigned short sem_num;
        short sem_op;
        short sem_flg;
}
*/
struct sembuf sem_a;
//单个信号量的V操作
sem_a.sem_num = 0;
sem_a.sem_op = 1;
//该标志表明,在系统退出后,自动释放该信号量
sem_a.sem_flg = SEM_UNDO;
if(semop(sem_mid,&sem_a,1) == -1)
{
perror("voperation_sem error");
return -1;
}
return 0;
}




/*
 *Name: poperation_sem()
 *Function: 信号量的p操作,使信号量的值减1,该部分代码与信号量的v操作代码类似
 *Arguement: 参数为信号量的标志符
 *Returnvalue:  出错返回-1,成功返回0.
 */


int poperation_sem(int sem_mid)
{
/*调用semop函数:int semop(int semid, struct sembuf *sops, unsigned nsops);
struct sembuf
{
        unsigned short sem_num;
        short sem_op;
        short sem_flg;
}
*/
struct sembuf sem_a;
//单个信号量的V操作
sem_a.sem_num = 0;
sem_a.sem_op = -1;
//该标志表明,在系统退出后,自动释放该信号量
sem_a.sem_flg = SEM_UNDO;
if(semop(sem_mid,&sem_a,1) == -1)
{
perror("voperation_sem error");
return -1;
}
return 0;
}



/********************************************************************************************************************************************************************/

/*
 *Author:
 *Filename: main.c
 *Description: 利用fork函数创建父子进程,利用信号量函数来解决同布与互斥问题。
 */




#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/sem.h>
#include <sys/ipc.h>


int main()
{
pid_t pid;
int sem_id;

//调用semget函数获得信号量标志符
sem_id = semget((key_t)1234,1,0666|IPC_CREAT);
if(sem_id == -1)
{
perror("semget error");
exit(-1);
}
//初始化信号量值为0
init_sem(sem_id,0);
//fork函数创建子进程
pid = fork();
if(pid == -1)
{
perror("fork error");
exit(-1);
}
else if(pid == 0)//进入子进程
{
printf("I am child process,i am working\n");
sleep(5);
voperation_sem(sem_id);//v操作对信号量+1
}
else
{
poperation_sem(sem_id);//P操作对信号量-1
printf("I am parent process.\n");
voperation_sem(sem_id);//v操作对信号量+1
delete_sem(sem_id);
}
exit(0);


}



结果:

说明,在使用信号量时,只能由一个进程来完成操作后,另一个进程才能获得信号量进行操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShaYQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值