博客
关于我
Linux信号量编程实例
阅读量:792 次
发布时间:2023-02-03

本文共 2616 字,大约阅读时间需要 8 分钟。

Linux信号量实现可控队列示例

本例展示了Linux信号量的基本用法,通过两个线程分别对一个公用队列进行入队和出队操作,利用信号量进行控制。当队列为空时,出队操作可以被阻塞;当队列满时,入队操作可以被阻塞。

常用的信号量函数包括:

  • sem_init:初始化信号量sem_t,可以指定初始值和是否共享。
  • sem_wait:一直阻塞等待直到信号量值大于0。
  • sem_timedwait:阻塞等待若干时间直到信号量值大于0。
  • sem_post:使信号量加1。
  • sem_destroy:释放信号量,与sem_init对应。

以下是实现可控队列的代码示例:

#ifndef MSGDEQUEUE_H#define MSGDEQUEUE_H#include "tmutex.h"#include 
#include
#include
#include
#include
using namespace std;template
class CMessageDequeue {public: CMessageDequeue(size_t MaxSize) : m_MaxSize(MaxSize) { sem_init(&m_enques, 0, m_MaxSize); sem_init(&m_deques, 0, 0); } ~CMessageDequeue() { sem_destroy(&m_enques); sem_destroy(&m_deques); } int sem_wait_i(sem_t *psem, int mswait) { if (mswait == -1) { return 0; } while (((rv = sem_wait(psem)) != 0) && (errno == EINTR)) { //屏蔽中断 } return rv; } bool push_back(const T& item, int mswait) { if (mswait == -1) { return false; } if (sem_wait_i(&m_enques, mswait) != 0) { //入队信号量被阻塞 return false; } // 定界加锁 AUTO_GUARD(g, MUTEX_TYPE, m_lock); try { m_data.push_back(item); cout << "push " << item << endl; sem_post(&m_deques); return true; } catch (...) { return false; } } bool pop_front(T& item, bool bpop, int mswait) { if (mswait == -1) { return false; } if (sem_wait_i(&m_deques, mswait) != 0) { return false; } // 定界加锁 AUTO_GUARD(g, MUTEX_TYPE, m_lock); try { item = m_data.front(); if (bpop) { m_data.pop_front(); cout << "pop " << item << endl; } sem_post(&m_enques); return true; } catch (...) { return false; } }private: MUTEX_TYPE m_lock; deque
m_data; size_t m_MaxSize; sem_t m_enques; sem_t m_deques;};

测试代码如下:

#include "msgdequeue.h"#include 
#include
#include using namespace std;void* get_thread(void* arg) { thread* t = (thread*)arg; while(true) { sleep(1000); // 每隔1秒取一次 int a = -1; if (qq.pop_front(a, true, 1000)) { cout << "pop failed. size=" << qq.size() << endl; } }}void* put_thread(void* arg) { int i = 0; while(i <= 30) { i++; if (qq.push_back(i, -1) == false) { cout << "无法入队" << endl; } } return NULL;}int main() { CMessageDequeue
qq(5); // 定义一个最大容量为5的队列 pthread_t pget, pput; pthread_create(&pget, NULL, get_thread, NULL); pthread_create(&pput, NULL, put_thread, NULL); pthread_join(pget, NULL); pthread_join(pput, NULL); return 0;}

编译命令:

g++ msgdequeue.h test.cpp -lpthread -lrt -o test

运行程序:

./test

说明:

  • 两个线程分别模拟入队和出队操作。
  • put_thread线程将30个元素依次入队,每入队5个元素后会阻塞。
  • get_thread线程每隔1000毫秒从队列取一个元素。
  • 队列最大容量为5,入队和出队操作都可以被信号量控制。

转载地址:http://mvzfk.baihongyu.com/

你可能感兴趣的文章
Linux-移动当前目录所有文件到上一级目录
查看>>
Linux-通过XShell使用sz命令提示找不到
查看>>
Linux.BackDoor.Chikdos/Elknot Attack And Defense Analysis
查看>>
Linux/CentOS设置全局代理(http)
查看>>
Linux/UNIX数据文件和信息系统
查看>>
Linux/Windows上Jenkins + Maven + Git的安装
查看>>
Linux0.11内核--几种地址(逻辑地址、线性地址、物理地址)的含义
查看>>
Linux3 在VMware中搭建CentOS6.5虚拟机
查看>>
Linux5
查看>>
Linux7/Centos7新特性之链路聚合
查看>>
linuxcbt-dhcpd
查看>>
Linux[crontab命令]–管理定时任务
查看>>
linux_DNS
查看>>
Linux_ERROR 1045 (28000): Access denied for user 'root'@'localhost'
查看>>
Linux_常用命令简单介绍(netstat,awk,top,tail,head,less,more,cat,nl)
查看>>
Linux_服务器_01_查看公网IP
查看>>
Linux——gcc编译器
查看>>
Linux——利用命名管道创建进程池
查看>>
Linux——匿名管道
查看>>
Linux——命令行参数及环境变量
查看>>