• system V信号量


        相对于Posix信号量,system V信号量提供了更为丰富的操作,如Posix信号量一次只能增减1,而system V则没有此限制;另外,可以用一个函数(semget)创建一组(多个)信号量,而Posix信号量一次只能创建一个;因此可用其模拟Posix信号量。功能丰富的同时也决定了System V信号量的复杂性。

    1)       相关函数:

    头文件:<sys/sem.h>

    创建或打开:semget

    操作:semop  包含的操作有:挂出和等待(对应增减的信号量只可以大于1)

    控制操作:semctl,主要用于初始化信号量集中信号量的初始值、获取相关状态(信号量值,semid_ds结构,相关操作的线程数信息)、删除、设置uid、gid、sem_perm.mode(读写权限)

    更详细的说明可以查看man手册,如man semget将获取函数的相关说明。

    2)       要点

    需要注意的是,由于System V信号量的创建和初始化工作是分两步进行的(不像Posix信号量创建和初始化是一个原子操作),这就需要相关的同步工作,确保A进程创建的信号量在被其他进程使用前已经被初始化。

    原理:当semget创建一个新的信号量集时,其semid_ds结构的sem_otime成员保证被置为0,因此,其他线程在成功调用semget打开信号量后,必须以IPC_STAT命令调用semctl.然后等待sem_otime变为非零值,这时就可以断定信号量已被初始化。

    代码表述如下:

    #define MSG_W(0400)
    #define MSG_R(0200)
    //permission formessage queues 660
    #defineSVMSG_MODE (MSG_R | MSG_W | MSG_R >> 3 | MSG_W >> 3)
    #define MAX_TIMES100
    union senum {
    int val;
    struct semid_ds *buf;
    usigned short*array;
    };
    int semid;
    int oflag =IPC_CREAT | IPC_EXEL | SVSEM_MODE;
    union senum arg;
    struct semid_ds seminfo;
    if (semid = semget(ftok(“/tmp/sem1”),1, oflag) >= 0)
    {
             // create successed, now set theinitial value
             arg.val = 1;
             semctl(semid, 0, SETVAL, arg);
    }
    else if (EEXIST== errno)
    {
             semid = semget(ftok(“/tmp/sem1”), 1,oflag);
             arg.buf = &seminfo;
             for (int i = 0; i < MAX_TIMES; i++)
             {
                       semctl(semid, 0, IPC_STAT,arg);
                       if (arg.buf->sem_otime !=0)
                       {
                                //here indicates initialsuccessed
                                break;
                       }
                       sleep(1);
             }
             if (MAX_TIMES == i)
             {
                      //aftertry MAX_TIMES, the semaphore still no been initialized
             }
    }

  • 相关阅读:
    用Sqoop进行Hive和MySQL之间的数据互导
    Spark读HBase写MySQL
    Kafka如何彻底删除topic及数据
    LDAP-HA安装与配置(Keepalived方式实现)
    配置两个Hadoop集群Kerberos认证跨域互信
    MYSQL HA 部署手册
    ELK简单安装测试
    Elasticsearch CURL命令
    大数据常见错误解决方案(转载)
    生成 RSA 公钥和私钥的方法
  • 原文地址:https://www.cnblogs.com/OpenLinux/p/5020694.html
Copyright © 2020-2023  润新知