首页 > 系统相关 >linux下实现event

linux下实现event

时间:2022-11-07 13:04:43浏览次数:40  
标签:实现 linux pEvent CEvent mutex pthread bool event


在linux下实现事件,主要采用条件锁的方式实现,源码如下:

首先是event.h文件,实现event类


#include <pthread.h>
#include <sys/time.h>

const int INFINITE = -1;
class CEvent
{
public:
CEvent(bool bIsManualReset, bool bInitialSignaled);
~CEvent();
bool CreateEvent();
bool Set();
bool Reset();
bool Wait(int cms);
private:
bool EnsureInitialized();
bool m_bIsManualReset;
bool m_bEventStatus;
bool m_bMutexInitialized;
pthread_mutex_t m_mutex;
bool m_bCondInitialized;
pthread_cond_t m_cond;
};

CEvent::CEvent(bool bIsManualReset, bool bInitialSignaled)
: m_bIsManualReset(bIsManualReset)
, m_bEventStatus(bInitialSignaled)
, m_bMutexInitialized(false)
, m_bCondInitialized(false)
{

}

CEvent::~CEvent()
{
if (m_bMutexInitialized)
{
pthread_mutex_destroy(&m_mutex);
m_bMutexInitialized = false;
}

if (m_bCondInitialized)
{
pthread_cond_destroy(&m_cond);
m_bCondInitialized = false;
}
}


bool CEvent::CreateEvent()
{
if (!m_bMutexInitialized)
{
if (0 == pthread_mutex_init(&m_mutex, NULL))
{
m_bMutexInitialized = true;
}
}

if (!m_bCondInitialized)
{
if (0 == pthread_cond_init(&m_cond, NULL))
{
m_bCondInitialized = true;
}
}

return ( m_bMutexInitialized && m_bCondInitialized);
}

bool CEvent::EnsureInitialized()
{
return ( m_bMutexInitialized && m_bCondInitialized);
}

bool CEvent::Set()
{
if (!EnsureInitialized())
{
return false;
}

pthread_mutex_lock(&m_mutex);
m_bEventStatus = true;
pthread_cond_broadcast(&m_cond);
pthread_mutex_unlock(&m_mutex);
return true;
}

bool CEvent::Reset()
{
if (!EnsureInitialized())
{
return false;
}

pthread_mutex_lock(&m_mutex);
m_bEventStatus = false;
pthread_mutex_unlock(&m_mutex);
return true;
}

bool CEvent::Wait(int cms)
{
if (!EnsureInitialized())
{
return false;
}

pthread_mutex_lock(&m_mutex);
int error = 0;

if (cms != INFINITE)
{
struct timeval tv;
gettimeofday(&tv, NULL);

struct timespec ts;
ts.tv_sec = tv.tv_sec + (cms / 1000);
ts.tv_nsec = tv.tv_usec * 1000 + (cms % 1000) * 1000000;

if (ts.tv_nsec >= 1000000000)
{
ts.tv_sec++;
ts.tv_nsec -= 1000000000;
}

while ((!m_bEventStatus) && (error == 0))
{
error = pthread_cond_timedwait(&m_cond, &m_mutex, &ts);
}
}
else
{
while ((!m_bEventStatus) && (error == 0))
{
error = pthread_cond_wait(&m_cond, &m_mutex);
}
}

if (0 == error && !m_bIsManualReset)
{
m_bEventStatus = false;
}

pthread_mutex_unlock(&m_mutex);

return (0 == error);
}


接下来是调用event类的文件main.cpp:

#include <unistd.h>
#include <assert.h>
#include <stdio.h>
#include "event.h"
CEvent *g_event = NULL;

CEvent *CreateEvent(bool bManualReset, bool bInitialState)
{
CEvent *pEvent = new CEvent(bManualReset, bInitialState);
assert(pEvent);

bool bRet = pEvent->CreateEvent();
assert(bRet);

return pEvent;
}

unsigned int WaitForSingleObject(CEvent *pEvent, int cms)
{
assert(pEvent);
if( pEvent->Wait(cms) )
{
return 0;
}

return 1;
}

bool CloseHandle(CEvent *pEvent)
{
delete pEvent;
}

bool SetEvent(CEvent *pEvent)
{
pEvent->Set();
}

bool ResetEvent(CEvent *pEvent)
{
pEvent->Reset();
}

void *pFunc1(void *pEvent)
{
while (1)
{
WaitForSingleObject(g_event, INFINITE);
printf("this is func1 print!\n");
sleep(1);
ResetEvent(g_event);
}
}

void *pFunc2(void *pEvent)
{
while (1)
{
sleep(5);
printf("this is func2 print!\n");
SetEvent(g_event);
}
}

int main()
{

//g_event = CreateEvent(false, true);
g_event = CreateEvent(true, true);

pthread_t pid1;
pthread_t pid2;

pthread_create(&pid1, NULL, pFunc1, NULL);
pthread_create(&pid2, NULL, pFunc2, NULL);

pthread_join(pid1, NULL);
pthread_join(pid2, NULL);

CloseHandle(g_event);
return 0;
}

在main.cpp文件中对事件类进行的使用函数进行封装,然后在两个线程中可以采用类似于windows中使用事件的形式来使用。上面的event事件同windows下一样,支持手动和自动。




标签:实现,linux,pEvent,CEvent,mutex,pthread,bool,event
From: https://blog.51cto.com/u_15862521/5828917

相关文章

  • flashpaper实现百度文库、豆丁网文档预览功能 - 坑
    最近公司实现一个类似百度文库的功能,发现FlashPaper还算能够不错的实现此需求。--后续会提到,这是一个坑首先讲下思路:1>安装FlashPaper;2>利用java代......
  • linux 后台挂起程序
    1.启动命令使用nohup命令挂起服务程序,启动命令如下nohuppython-utest.py>test_out.out2>&1&1命令含义说明:“nohup”:保证程序不被挂起末尾的“&”:表示后台运行......
  • 如何实现nvidia显卡的cuda的多kernel并发执行???
    相关:CPU端多进程/多线程调用CUDA是否可以加速??? ====================================================......
  • 基于k8s的发布系统的实现
    综述首先,本篇文章所介绍的内容,已经有完整的实现,可以参考这里。在微服务、DevOps和云平台流行的当下,使用一个高效的持续集成工具也是一个非常重要的事情。虽然市面上目前......
  • 基于vue-Ant实现图片上传
    引言:上传是将信息(网页、文字、图片、视频等)通过网页或者上传工具发布到远程服务器上的过程。如何使用Ant-design-vue中的a-upload上传组件进行图片或者视频的上传呢?正文:1.......
  • 记在Linux系统源码包安装MySQL
    记在Linux系统源码包安装MySQL实验环境:系统版本:CentOS7MySQL版本:5.7.39(https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.39-el7-x86_64.tar.gz)实验开始步......
  • linux 测试端口命令wget --- 比telnet更好
     wget11.11.255.11:20001三种返回:1ip不通 Connectingto11.11.255.11:20001... 2ip通端口不通 Connectingto11.11.255.11:20001...failed:Connectionrefused......
  • 如何安装nload对linux进行流量监控
    第一步:nload命令简介nload命令用于查看linux网络流量状况,实时输出。可以理解为是一个控制台应用程序,用来实时监测网络流量和带宽使用情况的命令。使用可视化的界面显示......
  • linux杀死进程
    ps-ef|grepflask|grep-vgrep|awk'{print$2}'|xargskill-9命令分析:命令作用ps-ef|grepflask找到所有flask进程grep-vgrep过滤包含......
  • 死磕Java面试系列:深拷贝与浅拷贝的实现原理
    深拷贝与浅拷贝的问题,也是面试中的常客。虽然大家都知道两者表现形式不同点在哪里,但是很少去深究其底层原理,也不知道怎么才能优雅的实现一个深拷贝。其实工作中也常常需要......