Linux消息循环并等待事件而不阻塞当前线程

时间:2021-11-08 00:00:45

How can we implement the following function for linux-like operating systems?

我们如何为类似Linux的操作系统实现以下功能?

The function has already been running on any windows version (Windows 98+) for about 15 years. It imitates multi-threading in a single thread and runs in both single or multi threading models, without blocking the invoking thread while waiting for the events. Recursive calls and returns may happen depending on outer-events but this simple function has always worked fine so far. The same logic MAY NOT be possible in linux, but a similar approach would be appreciable. (I haven't changed any letter of the function to keep it as it is. The variable names are a mixture of Turkish and English)

该功能已在任何Windows版本(Windows 98+)上运行了大约15年。它在单个线程中模仿多线程并在单线程或多线程模型中运行,而不会在等待事件时阻塞调用线程。可能会发生递归调用和返回,具体取决于外部事件,但这个简单的函数到目前为止一直运行良好。在linux中可能无法实现相同的逻辑,但类似的方法也是可以理解的。 (我没有更改函数的任何字母以保持原​​样。变量名称是土耳其语和英语的混合)

Thanks in advance!

提前致谢!

ERes __fastcall Bekle(HANDLE obj, int mls, int mod)
{
    JMSG  msg;
    DWORD ret, son = GetTickCount()+mls;

    while(0 <= mls)
    {
        ret = MsgWaitForMultipleObjects(1, &obj, FALSE, mls, mod);
        if (ret == WAIT_OBJECT_0)
             return wrOlur;      // The obj was signaled
        if (ret == WAIT_TIMEOUT)
             return wrSaat;      // Time expired event
        if (ret == WAIT_ABANDONED_0)
             return wrTerk;      // Abandoned
        if (ret == WAIT_FAILED)
             return wrFail;      // Failed anyway
        if (ret == 0xFFFFFFFF)
             return wrHata;      // Error returned

        while(PeekMessage(msg,NULL,NULL,NULL,PM_REMOVE))
        {
            TranslateMessage(msg);
            DispatchMessage(msg);
            if(WaitForSingleObject(obj, 0)==WAIT_OBJECT_0)
                return wrOlur; // Event is now signaled.
        }
        mls = son - GetTickCount();
    }

    return wrSaat;
}

1 个解决方案

#1


0  

There's nothing in the sample code that appears to be anything complicated. This looks like a typical message dispatching loop, and it would work exactly the same in Linux as it would in Windows, presuming you had some kind of a message queue that's being read from.

示例代码中没有任何内容似乎有任何复杂的内容。这看起来像一个典型的消息调度循环,它在Linux中的工作方式与在Windows中完全相同,假设你有一些正在读取的消息队列。

Additionally, POSIX specifies the poll() and select() system calls (you can find all the details by searching Google) which wait for any one of several file descriptors to become readable or writable. This is another way that single thread-based event dispatching gets typically implemented in Linux. You can poll() or select() to check if one or more file descriptors can be read or written from. If not, do something else, then try again. Otherwise, read whatever's to be read or written to, from the appropriate file descriptor, then move on.

此外,POSIX指定poll()和select()系统调用(您可以通过搜索Google查找所有详细信息),等待几个文件描述符中的任何一个变得可读或可写。这是基于线程的单个事件调度通常在Linux中实现的另一种方式。您可以使用poll()或select()来检查是否可以读取或写入一个或多个文件描述符。如果没有,请做其他事情,然后再试一次。否则,从适当的文件描述符中读取要读取或写入的内容,然后继续。

#1


0  

There's nothing in the sample code that appears to be anything complicated. This looks like a typical message dispatching loop, and it would work exactly the same in Linux as it would in Windows, presuming you had some kind of a message queue that's being read from.

示例代码中没有任何内容似乎有任何复杂的内容。这看起来像一个典型的消息调度循环,它在Linux中的工作方式与在Windows中完全相同,假设你有一些正在读取的消息队列。

Additionally, POSIX specifies the poll() and select() system calls (you can find all the details by searching Google) which wait for any one of several file descriptors to become readable or writable. This is another way that single thread-based event dispatching gets typically implemented in Linux. You can poll() or select() to check if one or more file descriptors can be read or written from. If not, do something else, then try again. Otherwise, read whatever's to be read or written to, from the appropriate file descriptor, then move on.

此外,POSIX指定poll()和select()系统调用(您可以通过搜索Google查找所有详细信息),等待几个文件描述符中的任何一个变得可读或可写。这是基于线程的单个事件调度通常在Linux中实现的另一种方式。您可以使用poll()或select()来检查是否可以读取或写入一个或多个文件描述符。如果没有,请做其他事情,然后再试一次。否则,从适当的文件描述符中读取要读取或写入的内容,然后继续。