c语言实现linux上类似windows的event事件

头文件:

#include <stdbool.h>

// 句柄
typedef void* EventHandle;

// 创建实例
EventHandle stCreateEvent(bool initState, bool manualReset);

// 释放实例
void stReleaseEvent(EventHandle handle);

// 等待事件。有信号返回true,否则false。无限等待时 waitTime_ms 置 0xffffffff。
bool stWaitEvent(EventHandle handle, unsigned int waitTime_ms);

// 重置事件为无信号
void stResetEvent(EventHandle handle);

// 事件设为有信号
void stSetEvent(EventHandle handle);

实现: 

#include "cEvent.h" // 这是头文件名字
#include <pthread.h>
#include <sys/time.h>
#include <errno.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>

typedef struct {
	bool m_state; // true : 有信号; false : 无信号
	bool m_manualReset;
	pthread_mutex_t m_mutex;
	pthread_cond_t m_cond;
} st_Event_Info;


EventHandle stCreateEvent(bool initState, bool manualReset)
{
	st_Event_Info* p = (st_Event_Info*)malloc(sizeof(st_Event_Info));
	if (p) {
		p->m_state = initState;
		p->m_manualReset = manualReset;
		pthread_mutex_init(&p->m_mutex, NULL);
		pthread_cond_init(&p->m_cond, NULL);
	}
	return p;
}

void stReleaseEvent(EventHandle handle)
{
	if (handle) {
		st_Event_Info* p = (st_Event_Info*)handle;
		// 		pthread_mutex_lock(&p->m_mutex);
		// 		p->m_state = false;
		// 		// 如果有等待中的,则激活全部
		// 		pthread_cond_broadcast(&p->m_cond);
		// 		pthread_mutex_unlock(&p->m_mutex);
		pthread_mutex_destroy(&p->m_mutex);
		while (EBUSY == pthread_cond_destroy(&p->m_cond)) {
			assert(0);
			usleep(10);
		}
		free(handle);
	}
}

bool stWaitEvent(EventHandle handle, unsigned int waitTime_ms)
{
	bool ret = true;
	st_Event_Info* p = (st_Event_Info*)handle;
	int waitRet = 0;
	if (handle) {
		pthread_mutex_lock(&p->m_mutex);
		if (p->m_state) {
			if (!p->m_manualReset)
				p->m_state = false;
			pthread_mutex_unlock(&p->m_mutex);
			return true;
		}
		if (waitTime_ms == 0xffffffff) {
			while (!p->m_state && waitRet == 0) {
				waitRet = pthread_cond_wait(&p->m_cond, &p->m_mutex);
			}
		}
		else if (waitTime_ms != 0) {
			struct timeval now;
			struct timespec outtime;
			gettimeofday(&now, NULL);
			outtime.tv_sec = now.tv_sec + waitTime_ms / 1000;
			outtime.tv_nsec = (now.tv_usec + (waitTime_ms % 1000) * 1000) * 1000;
			if (outtime.tv_nsec >= 1000000000) {
				++outtime.tv_sec;
				outtime.tv_nsec -= 1000000000;
			}
			while (!p->m_state && waitRet == 0) {
				waitRet = pthread_cond_timedwait(&p->m_cond, &p->m_mutex, &outtime);
			}
			if (waitRet == ETIMEDOUT) {
				ret = false;
			}
			else 
				assert(waitRet == 0);
		}
		else
			ret = p->m_state;
		if (waitRet == 0 && !p->m_manualReset) {
			p->m_state = false;
		}
		pthread_mutex_unlock(&p->m_mutex);
	}
	return ret;
}

void stResetEvent(EventHandle handle)
{
	if (handle) {
		st_Event_Info* p = (st_Event_Info*)handle;
		if (p->m_state)
		{
			pthread_mutex_lock(&p->m_mutex);
			p->m_state = false;
			pthread_mutex_unlock(&p->m_mutex);
		}
	}
}

void stSetEvent(EventHandle handle)
{
	if (handle) {
		st_Event_Info* p = (st_Event_Info*)handle;
		if (!p->m_state)
		{
			pthread_mutex_lock(&p->m_mutex);
			p->m_state = true;
			// 广播激活所有等待
			pthread_cond_broadcast(&p->m_cond);
			pthread_mutex_unlock(&p->m_mutex);
		}
	}
}


用法举例:

// 创建实例
EventHandle event = stCreateEvent(false, false);
...

// 线程1中等待信号
while(!stWaitEvent(event, 100)) {
    // do something
}
...
// 线程2:设置有信号
stSetEvent(event);
...
// 用完释放
stReleaseEvent(event);

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Linux 平台下,可以使用 X11 库来获取用户最后一次输入的时间。X11 库是一个用于图形界面的库,也提供了一些输入设备相关的功能。 具体实现步骤如下: 1. 引入 X11 头文件。 ``` #include <X11/Xlib.h> ``` 2. 连接 X 服务器。 ``` Display* display = XOpenDisplay(NULL); if (display == NULL) { // 连接 X 服务器失败 return; } ``` 3. 获取当前活动窗口的 ID。 ``` Window root_window = DefaultRootWindow(display); Window active_window; int revert_to; XGetInputFocus(display, &active_window, &revert_to); ``` 4. 获取最后一次输入的时间。 ``` XEvent event; memset(&event, 0, sizeof(event)); XQueryPointer(display, active_window, &event.xbutton.root, &event.xbutton.window, &event.xbutton.x_root, &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y, &event.xbutton.state, &event.xbutton.time); unsigned long last_input_time = event.xbutton.time; ``` 5. 关闭 X 服务器连接。 ``` XCloseDisplay(display); ``` 完整代码示例: ```c #include <X11/Xlib.h> #include <stdio.h> int main(void) { Display* display = XOpenDisplay(NULL); if (display == NULL) { printf("Failed to connect to X server.\n"); return 1; } Window root_window = DefaultRootWindow(display); Window active_window; int revert_to; XGetInputFocus(display, &active_window, &revert_to); XEvent event; memset(&event, 0, sizeof(event)); XQueryPointer(display, active_window, &event.xbutton.root, &event.xbutton.window, &event.xbutton.x_root, &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y, &event.xbutton.state, &event.xbutton.time); unsigned long last_input_time = event.xbutton.time; printf("Last input time: %lu\n", last_input_time); XCloseDisplay(display); return 0; } ``` 需要注意的是,Linux 平台下获取用户最后一次输入的时间并不像 Windows 平台下那样简单,需要使用 X11 库来实现

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值