Linux信号量实践(2)

信号量API综合实践

//实践1:封装PV原语
union mySemUn
{
    int              val;    // Value for SETVAL//
    struct semid_ds *buf;    // Buffer for IPC_STAT, IPC_SET//
    unsigned short  *array;  // Array for GETALL, SETALL//
    struct seminfo  *__buf;  // Buffer for IPC_INFO (Linux-specific)//
};

//封装V操作
int sem_V(int semid)
{
    struct sembuf buf = {0,+1,0};
    return semop(semid,&buf,1);
}
//封装P操作
int sem_P(int semid)
{
    struct sembuf buf = {0,-1,0};;
    return semop(semid,&buf,1);
}

int main()
{
    //创建或获取信号量
    int semid = semget(0x12345670,1,0666|IPC_CREAT);
    if (semid == -1)
    {
        err_exit("semget error");
    }

    //设置信号量的值
    int valueForSetSem = 0;
    cout << "Please input the value to set sem: ";
    cin >> valueForSetSem;

    union mySemUn setValue;
    setValue.val = valueForSetSem;
    //设置信号量
    if (semctl(semid,0,SETVAL,setValue) != 0)
    {
        err_exit("semctl SETVAL error");
    }

    //进入临界区
    sem_P(semid);
    cout << "Hello Xiaofang!" << endl;
    //退出临界区
    sem_V(semid);

    return 0;
}

//实践2:线程与信号量综合实践
union mySemUn
{
    int              val;    // Value for SETVAL//
    struct semid_ds *buf;    // Buffer for IPC_STAT, IPC_SET//
    unsigned short  *array;  // Array for GETALL, SETALL//
    struct seminfo  *__buf;  // Buffer for IPC_INFO (Linux-specific)//
};

//封装V操作
int sem_V(int semid)
{
    struct sembuf buf = {0,+1,0};
    return semop(semid,&buf,1);
}
//封装P操作
int sem_P(int semid)
{
    struct sembuf buf = {0,-1,0};;
    return semop(semid,&buf,1);
}

unsigned long long int count = 0;
void *threadForAddCount(void *arg)
{
    int semid = *static_cast<int *>(arg);
    for (;;)
    {
        sem_P(semid);
        ++ count;
        sem_V(semid);
    }
    pthread_exit(NULL);
}

void *threadForPrintCount(void *arg)
{
    for (;;)
    {
        cout << "count = " << count << endl;
        sleep(1);
    }
    pthread_exit(NULL);
}

int main()
{
    //创建或获取信号量
    int semid = semget(0x12345670,1,0666|IPC_CREAT);
    if (semid == -1)
    {
        err_exit("semget error");
    }

    //设置信号量的值
    int valueForSetSem = 0;
    cout << "Please input the value to set sem: ";
    cin >> valueForSetSem;

    union mySemUn setValue;
    setValue.val = valueForSetSem;
    //设置信号量
    if (semctl(semid,0,SETVAL,setValue) != 0)
    {
        err_exit("semctl SETVAL error");
    }

    pthread_t addThread[2];
    pthread_t printThread;
    //创建线程
    for (int i = 0; i < 2; ++i)
    {
        pthread_create(&addThread[i],NULL,threadForAddCount,&semid);
    }
    pthread_create(&printThread,NULL,threadForPrintCount,NULL);

    //等待线程终止
    for (int i = 0; i < 2; ++i)
    {
        pthread_join(addThread[i],NULL);
    }
    pthread_join(printThread,NULL);

    return 0;
}

void err_exit(std::string str)
{
    perror(str.c_str());
    exit(EXIT_FAILURE);
}

附-Makefile

CC = g++
CPPFLAGS = -Wall -g -pthread

BIN = main
SOURCES = $(BIN.=.cpp)

.PHONY: clean all 

all: $(BIN)

$(BIN): $(SOURCES)

clean:
    -rm -rf $(BIN) bin/ obj/ core
时间: 2024-09-29 02:02:31

Linux信号量实践(2)的相关文章

Linux信号量实践(1)

进程的同步与互斥 顺序程序与并发程序特征 顺序程序 并发程序 顺序性 共享性 封闭性:(运行环境的封闭性) 并发性 确定性 随机性 可再现性 进程互斥 由于各进程要求共享资源,而且有些资源需要互斥使用,因此各进程间竞争使用这些资源,进程的这种关系为进程的互斥. 系统中某些资源一次只允许一个进程使用,称这样的资源为临界资源或互斥资源. 在进程中涉及到互斥资源的程序段叫临界区. 互斥示例 说明:如果此时票数X=1,A进程与B进程同时抢到临界资源X,都执行X--,则会出现X<0的情况,这种情况肯定是不

Linux及安全——Linux基础实践

Linux及安全——Linux基础实践 一.实践一:掌握软件源的维护方法,配置系统使用教育网内的软件源镜像.掌握通过软件源来查找,安装,卸载,更新软件的方法. 1.软件源的维护方法 Ubuntu的软件源列表存放在/etc/apt/sourcers.list,为了安全起见,我们在对源文件进行操作之前,先将软件源备份. 打开终端,输入命令 sudo cp /etc/apt/sources.list/ etc/apt/backup_sources.list 即把软件源备份的文件backup_sourc

Linux课题实践三——字符集总结与分析

Linux课题实践三——字符集总结与分析 20135318  刘浩晨 字符是各种文字和符号的总称,包括各国家文字.标点符号.图形符号.数字等.字符集是多个字符的集合,字符集种类较多,每个字符集包含的字符个数不同,常见字符集名称:ASCII字符集.GB2312字符集.BIG5字符集. GB18030字符集.Unicode字符集等. 1.总结ISO.UCS/UTF.GB系列字符集的由来.异同 (1).ISO/IEC ISO/IEC 646:是国际标准化组织(ISO)及国际电工委员会(IEC)联合制定

linux信号量之进程间同步

概念 linux信号量:允许多个线程同时进入临界区,可以用于进程间的同步. 和互斥锁(mutex)的区别:互斥锁只允许一个线程进入临界区. 所在头文件:semaphore.h 主要函数 初始化函数 int sem_init(sem_t *sem, int pshared, unsigned int value) sem:要初始化的信号量 pshared:此信号量是在进程间共享还是线程间共享 value:信号量的初始值 删除函数 int sem_destroy(sem_t *sem) sem:要销

Linux基础实践

Linux基础实践 1.1 应用安装 要求:掌握软件源的维护方法,配置系统使用软件源镜像.掌握通过软件源来查找,安装,卸载,更新软件的方法 备份原地址列表文件:sudo cp /etc/apt/sources.list /etc/apt/sources.list.old 修改列表文件:sudo gedit /etc/apt/sources.list 源: deb http://mirrors.163.com/ubuntu/ trusty main multiverse restricted un

进程和程序:编写shell——《Unix/Linux编程实践教程》读书笔记(第8章)

1.Unix shell的功能 shell是一个管理进程和运行程序的程序.所有常用的shell都有3个主要功能: (1)运行程序: (2)管理输入和输出 (3)可编程 shell同时也是带有变量和流程控制的编程语言. 2.Unix的进程模型 一个程序是存储在文件中的机器指令序列,一般它是由编译器将源代码编译成二进制格式的代码.运行一个程序意味着将这些机器指令序列载入内存然后让处理器(CPU)逐条执行.在Unix术语中,一个可执行程序是一些机器指令机器数据的序列.一个进程是程序运行时的内存空间和设

系统调用操作文件——《Unix/Linux编程实践教程》读书笔记

1.who命令通过读系统日志的内容显示当前已经登录的用户. 2.Unix系统把数据存放在文件中,可以通过以下系统调用操作文件: open(filename, how) creat(filename, mode) read(fd, buffer, amt) write(fd, buffer, amt) lseek(fd, distance, base) close(fd) 3.进程对文件的读/写都要通过文件描述符,文件描述符表示文件和进程之间的连接. 4.每次系统调用都会导致用户模式和内核模式的切

终端控制和和信号——《Unix/Linux编程实践教程》读书笔记(第6章)

1.有些程序处理从特定设备来的数据.这些与特定设备相关的程序必须控制与设备的连接.Unix系统中最常见的设备是终端. 2.终端驱动程序有很多设置.各个设置的特定值决定了终端驱动程序的模式.为用户编写的程序通常需要设置终端驱动程序为特定的模式. 3.键盘输入分为3类,终端驱动程序对这些输入做不同的处理.大多数建代表常规数据,它们从驱动程序传输到程序.有些键调用驱动程序中的编辑函数.如果按下删除键,驱动程序将前一个字符从它的行缓冲中删除,并将命令发送到终端屏幕,使之从显示器中删除字符.最后,有些键调

Linux信号量详解

1.什么是信号量信号量是一种特殊的变量,访问具有原子性.只允许对它进行两个操作:1)等待信号量当信号量值为0时,程序等待:当信号量值大于0时,信号量减1,程序继续运行.2)发送信号量将信号量值加1. 我们使用信号量,来解决进程或线程间共享资源引发的同步问题. 2.Linux中信号量的使用Linux提供了一组信号量API,声明在头文件sys/sem.h中.1)semget函数:新建信号量 int semget(key_t key,int num_sems,int sem_flags); key:信