【问题标题】:Helping C++11 macros to run code with or without multithreading帮助 C++11 宏在有或没有多线程的情况下运行代码
【发布时间】:2016-09-28 08:41:16
【问题描述】:

我正在尝试创建一个预处理宏,该宏允许代码是多线程的还是不取决于运行时变量。 我的第一次尝试只是一个编译时宏并且有效,但运行时版本不是。

// Working compile-time version (defined in MultiThreadMacros.h)

#ifdef USE_MT

    #define MT_START(Thread)                              \
        std::atomic<bool> Thread ## Ret = true;           \
        std::thread Thread([&]()                          \
        {                                                 \
            std::atomic<bool> & __mtRet = Thread ## Ret;  \
            try{

    #define MT_END                                        \
            }catch(...){__mtRet = false;}                 \
    };

    #define MT_JOIN(Thread)                     \
        if (Thread.joinable()) Thread.join();   \
        if (Thread ## Ret){ throw; }

#else

    #define MT_START(Thread)
    #define MT_END

#endif

这是一个最小的使用示例

#define USE_MT
#include "MultiThreadMacros.h"

void function()
{
    int i = 0; 
    int j = 0;

    MT_START(th1)
    {
        i += 2;

        MT_START(th3)
        {
            i += 4;
        }
        MT_END;

        MT_JOIN(th3);
    }
    MT_END;

    MT_START(th2)
    {
        j += 2;
    }
    MT_END


    MT_JOIN(th1);
    MT_JOIN(th2);
}

现在是条件版本。如果条件为假,我将从用户代码创建一个 lambda 并执行 lambda,否则我将使用 lambda 启动一个线程。

这里的主要困难是编译时版本已经在项目中广泛使用,我正在尝试更改宏而不重写所有以前的代码(这会导致那些 __mt 引用)

#define MT_START(Thread, Cond)                           \
    std::thread Thread;                                  \
    std::atomic<bool> Thread ## Ret = true;              \
    {                                                    \
        auto & __mtTh = Thread;                          \
        const bool __mtCond = Cond;                      \
        auto __mtLambda = [&]() -> void                  \
        {                                                \
            std::atomic<bool> & __mtRet = Thread ## Ret; \
            try {

#define MT_END                                           \
            }catch(...){__mtRet = false;}                \
        };                                               \
        if (__mtCond)                                    \
        {                                                \
            __mtTh = std::thread{__mtLambda};            \
        }                                                \
        else                                             \
        {                                                \
            __mtLambda();                                \
        }                                                \
    }        

最后一个版本使单元测试随机失败,我不明白为什么最后一组宏与第一组不同。

如果有人可以提供帮助。 谢谢

【问题讨论】:

  • 我刚刚编辑了问题以更正示例@joachim-pileborg
  • throw;(没有要抛出的表达式)只能在 catch 子句或从中调用的函数中使用;否则它会表现出未定义的行为。鉴于此,您的MT_JOIN 没有多大意义。
  • 嗯,事实上这只是一个不正确的最小示例。
  • 您的问题在 20 年前就已经解决了。查看受 GCC 和 Clang 编译器(和其他)支持的 OpenMP。
  • 我了解 OpenMP,但这些宏适用于普通 C++11。

标签: multithreading c++11 lambda macros capture


【解决方案1】:

其实宏是可以工作的,是使用问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多