gpt4 book ai didi

c - 如何并行化 Windows 消息循环和 Hook 回调逻辑及其创建的 Ruby 线程?

转载 作者:太空宇宙 更新时间:2023-11-03 16:12:08 25 4
gpt4 key购买 nike

我正在开发一个免费、简单、希望是多平台的热键启动器工具,它是用 Ruby 编写的。

现在我正在努力解决 Windows 实现的一些线程问题。下面显示的概念代码的粗略证明在我的日常使用中已经可靠地工作:

HotkeyProcessor#process_keypress(脚注 1)在按下某个键时被 C 代码调用并随后处理该键事件。

问题

但是,当 process_keypress 启动一个线程 执行一些耗时的工作时(脚注 2),一个微妙的缺陷出现了:该程序的大部分时间都花在 C 扩展中,等待 get_message(脚注 3)返回 - 这在设计上永远不会发生。 Ruby 线程不会同时运行。线程执行仅在 Ruby 级代码处于控制之下时发生,因此当 #process_keypress 处于事件状态时,仅在每个键事件之后的几毫秒内发生。

在这种情况下是否可以连续并发执行?感谢您的任何建议!

require 'hotkey_processor'

def slowly_do_stuff
5.times { |i| sleep(0.1); print "#{i} " }
end

module HotkeyProcessor
def self.process_keypress(code, down) # footnote 1
print '. '
slowly_do_stuff if code == 65 and down # A pressed
Thread.new {slowly_do_stuff} if code == 66 and down # B pressed # footnote 2
true
end
end
puts 'Press A, B and other keys.'
HotkeyProcessor.start

热键处理器:

#include "ruby.h"
#include "windows.h"
#include <stdio.h>

int process_keypress_function;
VALUE HotkeyProcessor;
HHOOK keyboard_hook;

LRESULT CALLBACK callback_function(int Code, WPARAM wParam, LPARAM lParam)
{
PKBDLLHOOKSTRUCT kbd = (PKBDLLHOOKSTRUCT)lParam;

if (Code < 0 || Qtrue == rb_funcall(HotkeyProcessor,
process_keypress_function,
2,
INT2NUM(kbd->vkCode), /* code */
(wParam == WM_KEYDOWN ||
wParam == WM_SYSKEYDOWN) ?
Qtrue : Qfalse)) /* down */
{
return CallNextHookEx(keyboard_hook, Code, wParam, lParam);
}
else
return 1;
}

static BOOL get_message(MSG *msg)
{
return GetMessage(msg, 0, 0, 0);
}

static VALUE start(VALUE self)
{
HMODULE Module = GetModuleHandle(NULL);
MSG msg;

keyboard_hook = SetWindowsHookEx(WH_KEYBOARD_LL,
(HOOKPROC) callback_function,
Module,
0);

get_message(&msg); /* footnote 3 */

/* Never get here. Wait forever for get_message() to return
to keep the program alive and responding to callbacks. */
return self;
}

static VALUE process_keypress(VALUE self, VALUE code)
{
return Qnil;
}

void Init_hotkey_processor() {
HotkeyProcessor = rb_define_module("HotkeyProcessor");
rb_define_module_function(HotkeyProcessor,
"process_keypress",
process_keypress,
1);
rb_define_module_function(HotkeyProcessor,
"start",
start,
0);
process_keypress_function = rb_intern("process_keypress");
}

最佳答案

我不完全明白你在做什么,但是使用 PeekMessage 怎么样?哪个返回?

关于c - 如何并行化 Windows 消息循环和 Hook 回调逻辑及其创建的 Ruby 线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1285453/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com