首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >线程条件变量与win32事件(linux vs windows-ce)

线程条件变量与win32事件(linux vs windows-ce)
EN

Stack Overflow用户
提问于 2012-01-16 17:03:13
回答 2查看 10.3K关注 0票数 5

我正在arm imx27板上对Windows和Linux进行性能评估。代码已经为CE编写,并测量了执行不同内核调用所需的时间,例如使用OS原语(如互斥和信号量)、打开和关闭文件以及网络。

在我将这个应用程序移植到Linux (线程)的过程中,我偶然发现了一个我无法解释的问题。几乎所有的测试都显示性能从5倍提高到10倍,但不是我的版本的win32事件 (SetEventWaitForSingleObject),CE实际上“赢了”这个测试。

为了模拟我使用p线程条件变量的行为(我知道我的实现没有完全模拟CE版本,但它已经足够评估了)。

测试代码使用两个使用事件的“乒乓”线程。

Windows代码:

线程1: (我测量的线程)

代码语言:javascript
复制
HANDLE hEvt1, hEvt2;
hEvt1 = CreateEvent(NULL, FALSE, FALSE, TEXT("MyLocEvt1"));
hEvt2 = CreateEvent(NULL, FALSE, FALSE, TEXT("MyLocEvt2"));

ResetEvent(hEvt1);
ResetEvent(hEvt2);

for (i = 0; i < 10000; i++)
{
    SetEvent (hEvt1);
    WaitForSingleObject(hEvt2, INFINITE);
}        

线程2: (只是“响应”)

代码语言:javascript
复制
while (1)
{
    WaitForSingleObject(hEvt1, INFINITE);
    SetEvent(hEvt2);
}

Linux代码:

线程1: (我测量的线程)

代码语言:javascript
复制
struct event_flag *event1, *event2;
event1 = eventflag_create();
event2 = eventflag_create();

for (i = 0; i < 10000; i++)
{
    eventflag_set(event1);
    eventflag_wait(event2);
}

线程2: (只是“响应”)

代码语言:javascript
复制
while (1)
{
    eventflag_wait(event1);
    eventflag_set(event2);
}

我对eventflag_*的实现

代码语言:javascript
复制
struct event_flag* eventflag_create()
{
    struct event_flag* ev;
    ev = (struct event_flag*) malloc(sizeof(struct event_flag));

    pthread_mutex_init(&ev->mutex, NULL);
    pthread_cond_init(&ev->condition, NULL);
    ev->flag = 0;

    return ev;
}

void eventflag_wait(struct event_flag* ev)
{
    pthread_mutex_lock(&ev->mutex);

    while (!ev->flag)
        pthread_cond_wait(&ev->condition, &ev->mutex);

    ev->flag = 0;

    pthread_mutex_unlock(&ev->mutex);
}

void eventflag_set(struct event_flag* ev)
{
    pthread_mutex_lock(&ev->mutex);

    ev->flag = 1;
    pthread_cond_signal(&ev->condition);

    pthread_mutex_unlock(&ev->mutex);
}

struct

代码语言:javascript
复制
struct event_flag
{
    pthread_mutex_t mutex;
    pthread_cond_t  condition;
    unsigned int    flag;
};

问题:

  • 为什么我看不出这里的表现有进步?
  • 可以做些什么来提高性能(例如,是否有更快的方法来执行CEs行为)?
  • 我还不习惯对线程进行编码,我的实现中是否有错误可能会导致性能损失?
  • 是否有其他库可供选择?
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-01-16 22:56:01

请注意,在调用pthread_cond_signal()时不需要持有互斥对象,因此您可以通过在发出条件信号之前释放互斥对象来提高条件变量'event‘实现的性能:

代码语言:javascript
复制
void eventflag_set(struct event_flag* ev)
{
    pthread_mutex_lock(&ev->mutex);

    ev->flag = 1;

    pthread_mutex_unlock(&ev->mutex);

    pthread_cond_signal(&ev->condition);
}

这可能会防止唤醒的线程立即阻塞互斥体。

票数 3
EN

Stack Overflow用户

发布于 2013-03-13 19:28:08

只有当您有能力错过事件时,这种类型的实现才能工作。我只是测试了一下,遇到了很多死锁。造成这种情况的主要原因是条件变量只唤醒一个已经在等待的线程。以前发出的信号丢失了。

如果条件已经发出信号,则没有计数器与允许等待线程简单地继续的条件相关联。Windows事件支持这种类型的使用。

我想不出比使用信号量( POSIX版本非常容易使用)更好的解决方案,该信号量初始化为零,set()使用sem_post()wait()使用sem_wait()。您肯定会想到一种使用sem_getvalue()将信号量计数最多达到1的方法。

尽管如此,我不知道POSIX信号量是否只是Linux信号量的一个整洁接口,或者性能损失是什么。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8883512

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档