Linux 中的 WaitForSingleObject 和 WaitForMultipleObjects 等效吗?

发布于 2024-08-30 05:37:59 字数 250 浏览 5 评论 0原文

我正在将一个应用程序从 Windows 迁移到 Linux。我面临着 WaitForSingleObjectWaitForMultipleObjects 接口的问题。

在我的应用程序中,我生成多个线程,其中所有线程等待来自父进程的事件或每 t 秒定期运行。

我已经检查了 pthread_cond_timedwait,但我们必须为此指定绝对时间。

我如何在 Unix 中实现这个?

I am migrating an applciation from windows to linux. I am facing problem with respect to WaitForSingleObject and WaitForMultipleObjects interfaces.

In my application I spawn multiple threads where all threads wait for events from parent process or periodically run for every t seconds.

I have checked pthread_cond_timedwait, but we have to specify absolute time for this.

How can I implement this in Unix?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

深空失忆 2024-09-06 05:38:00

坚持使用pthread_cond_timedwait并使用clock_gettime。例如:

struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += 10; // ten seconds
while (!some_condition && ret == 0)
    ret = pthread_cond_timedwait(&cond, &mutex, &ts);

如果您愿意,可以将其包装在函数中。


更新:根据我们的评论补充答案。

POSIX 没有像 Windows 那样的单个 API 来等待“所有类型”的事件/对象。每一项都有其自己的功能。通知线程终止的最简单方法是使用原子变量/操作。例如:

主线程:

// Declare it globally (argh!) or pass by argument when the thread is created
atomic_t must_terminate = ATOMIC_INIT(0);

// "Signal" termination by changing the initial value
atomic_inc(&must_terminate); 

辅助线程:

// While it holds the default value
while (atomic_read(&must_terminate) == 0) {
    // Keep it running...
}
// Do proper cleanup, if needed
// Call pthread_exit() providing the exit status

另一种选择是使用 pthread_cancel 发送取消请求。被取消的线程必须调用pthread_cleanup_push来注册任何必要的清理处理程序。这些处理程序以与注册时相反的顺序调用。切勿从清理处理程序中调用 pthread_exit,因为这是未定义的行为。已取消线程的退出状态为 PTHREAD_CANCELED。如果您选择这种替代方案,我建议您主要阅读有关取消点和类型的信息。

最后但并非最不重要的一点是,调用 pthread_join 将使当前线程阻塞,直到参数传递的线程终止。作为奖励,您将获得线程的退出状态。

Stick to pthread_cond_timedwait and use clock_gettime. For example:

struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += 10; // ten seconds
while (!some_condition && ret == 0)
    ret = pthread_cond_timedwait(&cond, &mutex, &ts);

Wrap it in a function if you wish.


UPDATE: complementing the answer based on our comments.

POSIX doesn't have a single API to wait for "all types" of events/objects as Windows does. Each one has its own functions. The simplest way to notify a thread for termination is using atomic variables/operations. For example:

Main thread:

// Declare it globally (argh!) or pass by argument when the thread is created
atomic_t must_terminate = ATOMIC_INIT(0);

// "Signal" termination by changing the initial value
atomic_inc(&must_terminate); 

Secondary thread:

// While it holds the default value
while (atomic_read(&must_terminate) == 0) {
    // Keep it running...
}
// Do proper cleanup, if needed
// Call pthread_exit() providing the exit status

Another alternative is to send a cancellation request using pthread_cancel. The thread being cancelled must have called pthread_cleanup_push to register any necessary cleanup handler. These handlers are invoked in the reverse order they were registered. Never call pthread_exit from a cleanup handler, because it's undefined behaviour. The exit status of a cancelled thread is PTHREAD_CANCELED. If you opt for this alternative, I recommend you to read mainly about cancellation points and types.

And last but not least, calling pthread_join will make the current thread block until the thread passed by argument terminates. As bonus, you'll get the thread's exit status.

紫罗兰の梦幻 2024-09-06 05:38:00

无论如何,我们(NeoSmart Technologies)刚刚发布了一个开源(MIT 许可)库,名为 pevents其中实现POSIX 上的 WIN32 手动和自动重置事件,并包括 WaitForSingleObject 和 WaitForMultipleObjects 克隆。

虽然我个人建议您在 POSIX 机器上编码时使用 POSIX 多线程和信号范例,但如果您需要,pevents 会为您提供另一种选择。

For what it's worth, we (NeoSmart Technologies) have just released an open source (MIT licensed) library called pevents which implements WIN32 manual and auto-reset events on POSIX, and includes both WaitForSingleObject and WaitForMultipleObjects clones.

Although I'd personally advise you to use POSIX multithreading and signaling paradigms when coding on POSIX machines, pevents gives you another choice if you need it.

戏蝶舞 2024-09-06 05:38:00

我意识到这是一个老问题了,但对于任何其他偶然发现它的人来说,这个来源表明 pthread_join() 实际上与 WaitForSingleObject() 做同样的事情:

http://www.ibm.com/developerworks/linux/library/l-ipc2lin1/index.html

祝你好运!

I realise this is an old question now, but for anyone else who stumbles across it, this source suggests that pthread_join() does effectively the same thing as WaitForSingleObject():

http://www.ibm.com/developerworks/linux/library/l-ipc2lin1/index.html

Good luck!

情独悲 2024-09-06 05:38:00

对于带有 false WaitAllWaitForMultipleObjects ,请尝试以下操作:

#include <unistd.h>
#include <pthread.h>
#include <stdio.h>

using namespace std;

pthread_cond_t condition;
pthread_mutex_t signalMutex;
pthread_mutex_t eventMutex;
int finishedTask = -1;

void* task(void *data)
{
    int num = *(int*)data;
    // Do some
    sleep(9-num);
    // Task finished
    pthread_mutex_lock(&eventMutex); // lock until the event will be processed by main thread
    pthread_mutex_lock(&signalMutex); // lock condition mutex
    finishedTask = num; // memorize task number
    pthread_cond_signal(&condition);
    pthread_mutex_unlock(&signalMutex); // unlock condtion mutex
}

int main(int argc, char *argv[])
{
    pthread_t thread[10];

    pthread_cond_init(&condition, NULL);
    pthread_mutex_init(&signalMutex, NULL); // First mutex locks signal
    pthread_mutex_init(&eventMutex, NULL); // Second mutex locks event processing

    int numbers[10];

    for (int i = 0; i < 10; i++) {
        numbers[i] = i;
        printf("created %d\n", i); // Creating 10 asynchronous tasks
        pthread_create(&thread[i], NULL, task, &numbers[i]);
    }

    for (int i = 0; i < 10;)
    {
        if (finishedTask >= 0) {
            printf("Task %d finished\n", finishedTask); // handle event
            finishedTask = -1; // reset event variable
            i++;
            pthread_mutex_unlock(&eventMutex); // unlock event mutex after handling
        } else {
            pthread_cond_wait(&condition, &signalMutex); // waiting for event
        }
    }

    return 0;
}

For WaitForMultipleObjects with false WaitAll try this:

#include <unistd.h>
#include <pthread.h>
#include <stdio.h>

using namespace std;

pthread_cond_t condition;
pthread_mutex_t signalMutex;
pthread_mutex_t eventMutex;
int finishedTask = -1;

void* task(void *data)
{
    int num = *(int*)data;
    // Do some
    sleep(9-num);
    // Task finished
    pthread_mutex_lock(&eventMutex); // lock until the event will be processed by main thread
    pthread_mutex_lock(&signalMutex); // lock condition mutex
    finishedTask = num; // memorize task number
    pthread_cond_signal(&condition);
    pthread_mutex_unlock(&signalMutex); // unlock condtion mutex
}

int main(int argc, char *argv[])
{
    pthread_t thread[10];

    pthread_cond_init(&condition, NULL);
    pthread_mutex_init(&signalMutex, NULL); // First mutex locks signal
    pthread_mutex_init(&eventMutex, NULL); // Second mutex locks event processing

    int numbers[10];

    for (int i = 0; i < 10; i++) {
        numbers[i] = i;
        printf("created %d\n", i); // Creating 10 asynchronous tasks
        pthread_create(&thread[i], NULL, task, &numbers[i]);
    }

    for (int i = 0; i < 10;)
    {
        if (finishedTask >= 0) {
            printf("Task %d finished\n", finishedTask); // handle event
            finishedTask = -1; // reset event variable
            i++;
            pthread_mutex_unlock(&eventMutex); // unlock event mutex after handling
        } else {
            pthread_cond_wait(&condition, &signalMutex); // waiting for event
        }
    }

    return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文