zoukankan      html  css  js  c++  java
  • linux app 层信号量使用

    以下转自:
    http://hi.baidu.com/andio/blog/item/07bb5ec270e3bb26e4dd3be4.html

    俩种方法,一是sem_open,一是semget
    原理哥就不说了,百度一下,sem_open,网络上一大堆,直接上代码,是正经
    免责声明:
    1、 此代码为个人基于学习目的所写,如果有人运行次代码造成了不可预料的后果,比如硬盘损坏,原子弹爆炸等
    本人概不负责!!
    PS:
    BS一切照抄别人不用自己大脑想问题的人!
    BS一切只说原理不上代码的光说不练的人!
    代码分为3部分sem_sync.h a.c b.c
    此文姐妹片:利用semget方法 http://hi.baidu.com/andio/blog/item/3d6096d61223a03c06088b3f.html
    1. sem_sync.h

    #ifndef _SEM_SYNC_H_

    #define _SEM_SYNC_H_
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <stdio.h>
    #include <semaphore.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>

    char SEM_A_TASK_IS_FREE[]= "a_task_is_free";
    char SEM_B_TASK_IS_FREE[]= "b_task_is_free";

    #endif
    2 进程a
    #include "sem_sync.h"
    int main()
    {
    sem_t *sem_a_task_is_free;
    sem_t *sem_b_task_is_free;
    sem_a_task_is_free = sem_open(SEM_A_TASK_IS_FREE,O_CREAT,0644,1);
    sem_b_task_is_free=sem_open(SEM_B_TASK_IS_FREE,O_CREAT,0644,0);
    if(sem_a_task_is_free == SEM_FAILED||sem_b_task_is_free == SEM_FAILED)
    {
    perror("unable to create semaphore");
    sem_unlink(SEM_A_TASK_IS_FREE);
    exit(-1);
    }

    while(1==1)
    {
    printf("run a task......\n");
    getchar();

    sem_post(sem_a_task_is_free);
    printf("send->a_task_is_free\n");

    printf("\nwaite sem_b_task_is_free\n");
    sem_wait(sem_b_task_is_free);
    printf("recv<-sem_b_task_is_free\n");
    }

    sem_close(sem_a_task_is_free);
    sem_unlink(SEM_A_TASK_IS_FREE);
    _exit(0);
    }
    //gcc a.c -lpthread -o a

    3 进程b
    #include "sem_sync.h"

    int main()
    {
    sem_t *sem_a_task_is_free;
    sem_t *sem_b_task_is_free;
    sem_a_task_is_free = sem_open(SEM_A_TASK_IS_FREE,O_CREAT,0644,0);
    sem_b_task_is_free=sem_open(SEM_B_TASK_IS_FREE,O_CREAT,0644,1);
    if(sem_a_task_is_free == SEM_FAILED||sem_b_task_is_free == SEM_FAILED){
    perror("unable to create semaphore");
    sem_unlink(SEM_B_TASK_IS_FREE);

    exit(-1);
    }

    while(1==1){
    printf("\nrun b_task......\n");
    sleep(1);

    sem_post(sem_b_task_is_free);
    printf("send->sem_b_task_is_free\n");

    printf("\nwaite a_task_is_free\n");
    sem_wait(sem_a_task_is_free);
    printf("recv<-a_task_is_free\n");
    }
    sem_close(sem_a_task_is_free);
    sem_close(sem_b_task_is_free);

    sem_unlink(SEM_B_TASK_IS_FREE);
    exit(0);
    }
    //gcc b.c -lpthread -o b

    #./a
    #./b
    原理哥就不说了,百度一下,semget,网络上一大堆,直接上代码,是正经
    免责声明:
    1、 此代码为个人基于学习目的所写,如果有人运行次代码造成了不可预料的后果,比如硬盘损坏,原子弹爆炸等
    本人概不负责!!
    2、如果转载请标注出处!
    http://hi.baidu.com/andio/blog/item/3d6096d61223a03c06088b3f.html
    PS:

    BS一切照抄别人不用自己大脑想问题的人!
    BS一切只说原理不上代码的光说不练的人!
    代码分为4部分usr_sem.h a.c b.c Makefile。
    此文姐妹篇:利用sem_open方法,http://hi.baidu.com/andio/blog/item/07bb5ec270e3bb26e4dd3be4.html
    1. usr_sem.h

    #ifndef _usr_sem_h_
    #define _usr_sem_h_
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/sem.h>
    #include <errno.h>
    /*
    利用ftok函数实现 关键key
    */

    #define SEM_KEY ftok("/",12)

    union semun{
    int val;
    struct semid_ds *buf;
    unsigned short *array;
    };
    /*
    声明共用信号量集合
    */

    struct sembuf p_start_a_task= {0,-1,SEM_UNDO},
    p_start_b_task = {1,-1,SEM_UNDO},
    v_a_task_is_end= {1,1,SEM_UNDO},
    v_b_task_is_end = {0,1,SEM_UNDO};

    /*
    SEM_CREAT(semid)
    这个 宏 的主要功能是创建信号量,并将其标识符
    赋给semid
    usr_sem_creat(semid) 调用了该宏
    */

    #define SEM_CREAT(semid) \
    if((semid = semget(SEM_KEY,2,0600 | IPC_CREAT | IPC_EXCL))<0)\
    {\
    if(errno==EEXIST)\
    {\
    semid = semget(SEM_KEY,2,0600 | IPC_CREAT);\
    if(semid<0)\
    printf("semget error");\
    }\
    }
    #define usr_sem_creat(semid)\
    SEM_CREAT(semid)

    /*
    SEM_SETVALUE(SEM_ID,SEM_INDEX,SEMUN,VALUE)\
    这个 宏 的主要功能是给信号量赋值,
    @SEM_ID:标识符
    @SEM_INDEX:索引
    @SEMUN:联合体,
    @VALUE:值
    usr_sem_set_value(SEM_ID,SEM_INDEX,SEMUN,VALUE) 调用了该宏
    */

    #define SEM_SETVALUE(SEM_ID,SEM_INDEX,SEMUN,VALUE)\
    SEMUN.val = VALUE;\
    if(semctl(SEM_ID,SEM_INDEX,SETVAL,SEMUN)<0)\
    printf("semctl sem %d error",SEM_INDEX);

    #define usr_sem_set_value(SEM_ID,SEM_INDEX,SEMUN,VALUE) \
    SEM_SETVALUE(SEM_ID,SEM_INDEX,SEMUN,VALUE)

    /*
    usr_sem_wait(SEM_ID,P)
    usr_sem_post(SEM_ID,V)
    模拟sem_wait,sem_post函数
    @SEM_ID:标识符
    @P:P类型信号量
    @V:V类型信号量,
    @VALUE:值
    usr_sem_set_value(SEM_ID,SEM_INDEX,SEMUN,VALUE) 调用了该宏
    */

    #define usr_sem_wait(SEM_ID,P)\
    semop(SEM_ID,&P,1);

    #define usr_sem_post(SEM_ID,V)\
    semop(SEM_ID,&V,1);
    #endif
    2. a.c
    #include "usr_sem.h"
    /*
    此代码断的主要功能是模拟a进程
    */

    int main()
    {

    /*变量声明*/
    int semid;
    union semun arg;
    /*宏操作实现信号量创建和赋值等*/

    usr_sem_creat(semid);
    usr_sem_set_value(semid,0,arg,1);
    usr_sem_set_value(semid,1,arg,0);
    printf("\n**********U can press enter key to continue this task!**************\n");
    /*
    while(1)模拟定时任务结构
    程序结构
    while(1)
    {
    usr_sem_wait(semid,p_start_a_task);
    <s>//访问临界区域的 代码
    usr_sem_post(semid,v_a_task_is_end);
    }
    */

    while(1)
    {
    printf("\n <===is rcving p_start_a_task.......\n");
    usr_sem_wait(semid,p_start_a_task);
    printf("rcv p_start_a_task.......[OK]\nin %s,running a_task[%d]......\n",__FILE__,random());
    getchar();
    printf("finish a_task,now is snding v_a_task_is_end..... \n");

    usr_sem_post(semid,v_a_task_is_end);
    printf(" ===>snd v_a_task_is_end.......[OK]\n");
    }
    }
    3. b.c
    #include "usr_sem.h"
    /*
    此代码断的主要功能是模拟b进程
    */

    int main()
    {
    int semid;

    union semun arg;
    /*
    宏操作实现信号量创建和赋值等
    */

    usr_sem_creat(semid);
    usr_sem_set_value(semid,0,arg,1);
    usr_sem_set_value(semid,1,arg,0);

    /*
    程序结构
    while(1)
    {
    usr_sem_wait(semid,p_start_b_task);
    <s>//访问临界区域的 代码
    usr_sem_post(semid,v_b_task_is_end);

    }
    */

    while(1){
    printf("\n <===is rcving p_start_b_task.......\n");
    usr_sem_wait(semid,p_start_b_task);
    printf("rcv p_start_b_task.......[OK]\nin %s,running b_task[%d]......\n",__FILE__,random());

    printf("finish b_task,now is snding v_b_task_is_end..... \n");
    usr_sem_post(semid,v_b_task_is_end);
    printf(" ===>snd v_b_task_is_end.......[OK]\n");
    }
    }

    4. Makefile
    #makefil
    #CROSS_COMPILE = /opt/EmbedSky/4.3.3/bin/arm-linux-
    CROSS_COMPILE =
    CC = $(CROSS_COMPILE)gcc
    LNK = $(CROSS_COMPILE)ld
    AR = $(CROSS_COMPILE)ar

    CFLAG=-o
    all:
    t$(CC) $(CFLAG) a a.c
    t$(CC) $(CFLAG) b b.c
    clean:
    trm -f *.o
  • 相关阅读:
    ACM: HDU 2544 最短路-Dijkstra算法
    ACM: HDU 1874 畅通工程续-Dijkstra算法
    ACM: SGU 101 Domino- 欧拉回路-并查集
    ACM: HDU 1285 确定比赛名次
    ACM: hdu 2647 Reward -拓扑排序
    ACM: hdu 1811 Rank of Tetris
    ACM: poj 1094 Sorting It All Out
    ACM: hihicoder #1174 : 拓扑排序·一 STL- queue
    ACM: CodeForces 140A New Year Table-数学几何
    POJ 3122 Pie 二分枚举
  • 原文地址:https://www.cnblogs.com/fishoneseaatblog/p/2353131.html
Copyright © 2011-2022 走看看