C语言 在 Linux 中,WaitForSingleObject 和 WaitForMultipleObjects 是等价的吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2719580/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:17:54  来源:igfitidea点击:

WaitForSingleObject and WaitForMultipleObjects equivalent in Linux?

clinuxmultithreadingsynchronizationporting

提问by Poorna

I am migrating an applciation from windows to linux. I am facing problem with respect to WaitForSingleObjectand WaitForMultipleObjectsinterfaces.

我正在将应用程序从 Windows 迁移到 linux。我在WaitForSingleObjectWaitForMultipleObjects接口方面面临问题。

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

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

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

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

How can I implement this in Unix?

我如何在 Unix 中实现它?

采纳答案by jweyrich

Stick to pthread_cond_timedwaitand use clock_gettime. For example:

坚持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);

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:

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

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_pushto register any necessary cleanup handler. These handlers are invoked in the reverse order they were registered. Never call pthread_exitfrom 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.

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

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

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

回答by Mahmoud Al-Qudsi

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

值得一提的是,我们(NeoSmart Technologies)刚刚发布了一个名为pevents 的开源(MIT 许可)库,它在 POSIX 上实现了 WIN32 手动和自动重置事件,并且包括 WaitForSingleObject 和 WaitForMultipleObjects 克隆。

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.

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

回答by eskimo9

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():

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

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

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

Good luck!

祝你好运!

回答by Sorcerer

For WaitForMultipleObjectswith false WaitAlltry this:

对于WaitForMultipleObjectsWaitAll试试这个:

#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;
}