Mac OS X:增强进程间信号量 timed_wait:CPU 消耗异常

发布于 2024-09-08 15:44:40 字数 3477 浏览 7 评论 0原文

将一段代码从 Windows 移植到 Mac OS X 后,我发现它在运行时消耗了整个 CPU 核心;负责CPU消耗的调用是boost::interprocess::interprocess_semaphore::timed_wait。

下面是重现此行为的代码部分。

#include <boost/interprocess/sync/interprocess_semaphore.hpp>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>

#include <boost/thread/thread_time.hpp>

#include <iostream>

static bool gStopRequested(false);

struct ShmObj
{
    boost::interprocess::interprocess_semaphore mSemaphore;
    ShmObj() : mSemaphore(0) {};
    ~ShmObj() {};
};

int main(char* argc, const char** argv)
{
    boost::interprocess::shared_memory_object* lShmObj = NULL;
    std::string lShmObjName("My_Boost_Interprocess_Test");
    boost::interprocess::mapped_region* lRegion;
    ShmObj* lObj;

    //Create shared segment
    try
    {
        lShmObj = new boost::interprocess::shared_memory_object(boost::interprocess::create_only, lShmObjName.c_str(), boost::interprocess::read_write);
    }
    catch (boost::interprocess::interprocess_exception &ex)
    {
        if (ex.get_error_code() != boost::interprocess::already_exists_error)
        {
            std::cerr << "Some error" << std::endl;
            exit(1);
        }
        else
        {
            std::cerr << "Already exists, just taking it back." << std::endl;
            try
            {
                lShmObj = new boost::interprocess::shared_memory_object(boost::interprocess::open_only, lShmObjName.c_str(), boost::interprocess::read_write);
            }
            catch (boost::interprocess::interprocess_exception &ex2)
            {
                std::cerr << "D'oh !" << std::endl;
                exit(1);
            }
        }
    }
    if (!lShmObj)
    {
        exit(1);
    }
    lShmObj->truncate(sizeof(ShmObj));
    lRegion = new boost::interprocess::mapped_region(*lShmObj, boost::interprocess::read_write);
    lObj = new (lRegion->get_address()) ShmObj;

    // The loop
    while (!gStopRequested)
    {
        boost::system_time lDeadlineAbsoluteTime = boost::get_system_time() + boost::posix_time::milliseconds(500);

        if (lObj->mSemaphore.timed_wait(lDeadlineAbsoluteTime))
        {
            std::cout << "acquired !" << std::endl;
        }
        else
        {
            std::cout << "tick" << std::endl;
        }
    }
}

然后,我读到未命名的信号量在 Mac OS X 下不可用,所以我认为这可能是因为未命名的信号量没有被有效地模拟......然后我尝试了以下操作,但没有成功:

#include <boost/interprocess/sync/named_semaphore.hpp>
#include <boost/thread/thread_time.hpp>

#include <iostream>

static bool gStopRequested(false);

int main(char* argc, const char** argv)
{
    boost::interprocess::named_semaphore::remove("My_Boost_Interprocess_Test");
    boost::interprocess::named_semaphore lMySemaphore(boost::interprocess::open_or_create, "My_Boost_Interprocess_Test", 1);

    // The loop
    while (!gStopRequested)
    {
        boost::system_time lDeadlineAbsoluteTime = boost::get_system_time() + boost::posix_time::milliseconds(500);

        if (lMySemaphore.timed_wait(lDeadlineAbsoluteTime))
        {
            std::cout << "acquired !" << std::endl;
        }
        else
        {
            std::cout << "tick" << std::endl;
        }
    }
}

我实际上期望 boost:: Mac OS X 上的进程间是因为可用的 Posix 原语,但实际上并非如此。有解决办法吗?多谢。

After porting a code segment from Windows to Mac OS X, I found it to consume a whole CPU core while running; the responsible call for the CPU consumption is boost::interprocess::interprocess_semaphore::timed_wait.

Here follows the code portion which reproduces this behaviour.

#include <boost/interprocess/sync/interprocess_semaphore.hpp>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>

#include <boost/thread/thread_time.hpp>

#include <iostream>

static bool gStopRequested(false);

struct ShmObj
{
    boost::interprocess::interprocess_semaphore mSemaphore;
    ShmObj() : mSemaphore(0) {};
    ~ShmObj() {};
};

int main(char* argc, const char** argv)
{
    boost::interprocess::shared_memory_object* lShmObj = NULL;
    std::string lShmObjName("My_Boost_Interprocess_Test");
    boost::interprocess::mapped_region* lRegion;
    ShmObj* lObj;

    //Create shared segment
    try
    {
        lShmObj = new boost::interprocess::shared_memory_object(boost::interprocess::create_only, lShmObjName.c_str(), boost::interprocess::read_write);
    }
    catch (boost::interprocess::interprocess_exception &ex)
    {
        if (ex.get_error_code() != boost::interprocess::already_exists_error)
        {
            std::cerr << "Some error" << std::endl;
            exit(1);
        }
        else
        {
            std::cerr << "Already exists, just taking it back." << std::endl;
            try
            {
                lShmObj = new boost::interprocess::shared_memory_object(boost::interprocess::open_only, lShmObjName.c_str(), boost::interprocess::read_write);
            }
            catch (boost::interprocess::interprocess_exception &ex2)
            {
                std::cerr << "D'oh !" << std::endl;
                exit(1);
            }
        }
    }
    if (!lShmObj)
    {
        exit(1);
    }
    lShmObj->truncate(sizeof(ShmObj));
    lRegion = new boost::interprocess::mapped_region(*lShmObj, boost::interprocess::read_write);
    lObj = new (lRegion->get_address()) ShmObj;

    // The loop
    while (!gStopRequested)
    {
        boost::system_time lDeadlineAbsoluteTime = boost::get_system_time() + boost::posix_time::milliseconds(500);

        if (lObj->mSemaphore.timed_wait(lDeadlineAbsoluteTime))
        {
            std::cout << "acquired !" << std::endl;
        }
        else
        {
            std::cout << "tick" << std::endl;
        }
    }
}

Then, I read that unnamed semaphores were not available under Mac OS X, so I thought it could be because unnamed semaphores were not efficiently emulated... I then tried the following, unsucessfully:

#include <boost/interprocess/sync/named_semaphore.hpp>
#include <boost/thread/thread_time.hpp>

#include <iostream>

static bool gStopRequested(false);

int main(char* argc, const char** argv)
{
    boost::interprocess::named_semaphore::remove("My_Boost_Interprocess_Test");
    boost::interprocess::named_semaphore lMySemaphore(boost::interprocess::open_or_create, "My_Boost_Interprocess_Test", 1);

    // The loop
    while (!gStopRequested)
    {
        boost::system_time lDeadlineAbsoluteTime = boost::get_system_time() + boost::posix_time::milliseconds(500);

        if (lMySemaphore.timed_wait(lDeadlineAbsoluteTime))
        {
            std::cout << "acquired !" << std::endl;
        }
        else
        {
            std::cout << "tick" << std::endl;
        }
    }
}

I was actually expecting a better behaviour of boost::interprocess on Mac OS X because of the available Posix primitives, but it is actually not. Any idea for a resolution? Thanks a lot.

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

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

发布评论

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

评论(1

累赘 2024-09-15 15:44:40

我成功地使用了 Mach 信号量而不是 boost::interprocess 的信号量...参见 http://pkaudio.blogspot.com/2010/05/mac-os-x-no-timed-semaphore-waits.html

I successfully Used Mach semaphores instead of the ones of boost::interprocess... see http://pkaudio.blogspot.com/2010/05/mac-os-x-no-timed-semaphore-waits.html

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