如何在多线程MEX功能中打印到控制台? [英] How do you print to console in a Multi-Threaded MEX Function?

查看:115
本文介绍了如何在多线程MEX功能中打印到控制台?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个使用Boost库的简单生产者消费者MEX函数.我已设法使以下程序正常运行.

I'm writing a simple producer consumer MEX function which uses the Boost library. I have manged to get the following program to work without any issues.

#include "mex.h"
#include <boost/thread/thread.hpp>
#include <boost/lockfree/spsc_queue.hpp>
#include <iostream>
#include <boost/atomic.hpp>

int producer_count = 0;
boost::atomic_int consumer_count (0);
boost::lockfree::spsc_queue<int, boost::lockfree::capacity<1024> > spsc_queue;
const int iterations = 10000000;

void producer()
{
    for (int i = 0; i != iterations; ++i) {
        int value = ++producer_count;
        while (!spsc_queue.push(value));
    }
}

boost::atomic<bool> done (false);

void consumer()
{
    int value;
    while (!done) {
        while (spsc_queue.pop(value))
            ++consumer_count;
    }

    while (spsc_queue.pop(value))
        ++consumer_count;
}

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    if (!spsc_queue.is_lock_free())
    {
      mexPrintf("boost::lockfree::queue is not lockfree\n");
      mexEvalString("drawnow;");
    }
    else
    {
      mexPrintf("boost::lockfree::queue is lockfree\n");
      mexEvalString("drawnow;");
    }

    boost::thread producer_thread(producer);
    boost::thread consumer_thread(consumer);

    producer_thread.join();
    done = true;
    consumer_thread.join();

    cout << "produced " << producer_count << " objects." << endl;
    cout << "consumed " << consumer_count << " objects." << endl;
}

最大的问题是,我尝试将 mexPrintf()包含在MATLAB崩溃的生产者或消费者方法中.经过调查后,我发现

The big problem is I try to include a mexPrintf() into the either the producer or consumer method MATLAB just crashes. After doing some investigation I found this post which explained this happens because of race conditions. Does anyone know how I can fix this issue? I read what the answer said about Mutex, but I do not understand how I would implement such a functionality.

推荐答案

除主线程外,您无法从任何线程调用 mexPrintf .互斥锁不能解决您的问题.

You cannot call mexPrintf from any thread except the main thread. A mutex will not solve your problem.

MATLAB文档:

MEX API线程不安全

请勿在MEX文件的单独线程上调用MATLAB®的单个会话.MEX和Matrix库API不是多线程的.

Do not call a single session of MATLAB® on separate threads from a MEX file. The MEX and Matrix Library APIs are not multi-threaded.

您可以从C MEX文件创建线程;但是,不支持从这些线程访问MATLAB.请勿从生成的线程中调用任何MEX API函数,包括在 mex.h 头文件中定义为 mexPrintf printf ./p>

You can create threads from a C MEX file; however, accessing MATLAB from those threads is not supported. Do not call any MEX API functions from the spawned threads, including printf, which is defined as mexPrintf in the mex.h header file.

如果您确实需要从这些线程中产生输出,请考虑实现一个简单的消息传递系统,在该系统中,线程将发布带有要输出的文本和主线程的消息,而不是等待 producer_thread.join(); ,循环查找要打印的消息,然后使用 mexPrintf 进行打印.

If you really need to produce output from these threads, consider implementing a simple messaging system where the threads post a message with the text to be output, and the main thread, instead of waiting with producer_thread.join();, sits in a loop looking for messages to print, and prints them with mexPrintf.

以下代码未经测试.它甚至没有被编译.考虑一下它是伪代码.我认为这是解决方案的合理尝试,但可能会有更好的方法.继续自行承担风险.:)

The code below is not tested. It's not even been compiled. Consider it pseudo-code. I think this is a reasonable attempt at a solution but there might be much better approaches. Continue at your own risk. :)

boost::lockfree::queue<std::string> message_queue;

void producer() {
    //...
    message_queue.push("A string to print!");
    //...
}

void mexFunction( /*...*/ ) {
    // ...
    boost::thread producer_thread(producer);
    boost::thread consumer_thread(consumer);
    while(producer_thread.joinable()) {
        join_for(boost::chrono::milliseconds(50));
        std::string s;
        while (message_queue.pop(s)) {
            mexPrintf("%s\n", s.c_str());
        }
    }
    producer_thread.join();
    done = true;
    consumer_thread.join();
    // ...
}

这篇关于如何在多线程MEX功能中打印到控制台?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆