转换为void *以将对象传递给cthread中的pthread [英] casting to void* to pass objects to pthread in c++

查看:158
本文介绍了转换为void *以将对象传递给cthread中的pthread的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有点困惑,如何传递一个对象到pthread_create函数。我发现了很多关于转换为void *,传递参数到pthread_create等等的零碎的信息,但没有什么连接它。我只是想确保我把它捆绑在一起,不做任何愚蠢的。假设我有以下线程类:
Edit: fixed mis-matched static_cast

I'm a little confused about how to pass an object to the pthread_create function. I've found a lot of piecemeal information concerning casting to void*, passing arguments to pthread_create, etc., but nothing that ties it all together. I just want to make sure I've tied it all together and am not doing anything stupid. Let's say I have the following thread class: fixed mis-matched static_cast.

class ProducerThread {
    pthread_t thread;
    pthread_attr_t thread_attr;
    ProducerThread(const ProducerThread& x);
    ProducerThread& operator= (const ProducerThread& x);
    virtual void *thread_routine(void *arg) {
        ProtectedBuffer<int> *buffer = static_cast<ProtectedBuffer<int> *> arg;
        int randomdata;

        while(1) {
            randomdata = RandomDataGen();
            buffer->push_back(randomdata);
        }

        pthread_exit();
    }
public:
    ProtectedBuffer<int> buffer;

    ProducerThread() {
        int err_chk;

        pthread_attr_init(&thread_attr);
        pthread_attr_setdetachstate(&thread_attr,PTHREAD_CREATE_DETACHED);

        err_chk = pthread_create(&thread, &thread_attr, thread_routine, static_cast<void *> arg);
        if (err_chk != 0) {
            throw ThreadException(err_chk);
        }
    }
    ~ProducerThread() {
        pthread_cancel(&thread);
        pthread_attr_destroy(&thread_attr);
    }
}

c> ProtectedBuffer 类只能使用 ProtectedBuffer :: push_back(int arg)的方法访问,它们使用互斥来保护实际数据。

To clarify, the data in the ProtectedBuffer class can only be accessed with methods like ProtectedBuffer::push_back(int arg), which use mutexes to protect the actual data.

我的主要问题是:我是否正确使用 static_cast ?我的第二个问题是我需要在 virtual void * thread_routine(void * arg)中的第一行,其中我将传递的void指针复制到 ProtectedBuffer

My main question is: am I using static_cast correctly? And my secondary question is do I need that first line in virtual void *thread_routine(void *arg) where I copy the passed void pointer to a pointer to ProtectedBuffer?

此外,如果我做了其他可能导致问题的事情,

Also, if I've done anything else that might cause problems, I'd appreciate hearing it.

推荐答案

如果你想走这条路,我相信你想要这样的:

If you want to go this route, I believe you want something like this:

修改:根据James Kanze的回答,添加一个单独的激活方法,以便在构建完成后启动该线程。

Based on James Kanze's answer, add a separate activate method to launch the thread after construction is finished.

class GenericThread {
protected:
    GenericThread () {
      //...
    }
    virtual ~GenericThread () {}

    int activate () {
        return pthread_create(..., GenericThreadEntry, this);
    }

    virtual void * thread_routine () = 0;

    #if 0
    // This code is wrong, because the C routine callback will do so using the
    // C ABI, but there is no guarantee that the C++ ABI for static class methods
    // is the same as the C ABI.
    static void * thread_entry (void *arg) {
        GenericThread *t = static_cast<GenericThread *>(arg);
        return t->thread_routine();
    }
    #endif
};

extern "C" void * GenericThreadEntry (void *) {
    GenericThread *t = static_cast<GenericThread *>(arg);
    return t->thread_routine();
}

然后, ProducerThread 将从 GenericThread 派生。

编辑: 搜索 externC。没有要求函数指针必须指向具有C链接的函数,以便通过C库例程调用。由于指针正在传递,链接要求不适用,因为链接用于解析名称。指向静态方法的指针是一个函数指针,根据C ++ 2011草案(n3242),Sec。 3.9.2p3:

Searching for extern "C" in the C++ Standard. revealed no requirement that a function pointer must point to a function with C linkage to be callable by a C library routine. Since pointers are being passed, linkage requirements do not apply, as linkage is used to resolve names. A pointer to a static method is a function pointer, according to C++ 2011 draft (n3242), Sec. 3.9.2p3:


除了指向静态成员的指针,引用指针的文本不适用于成员的指针。 / p>

Except for pointers to static members, text referring to pointers does not apply to pointers to members.

编辑: Mea culpa。C库将调用回调函数C应用二进制接口。具有C ++链接的函数可以使用与C ABI不同的ABI。这就是为什么当传递到C库的回调函数时,需要使用 externC链接的函数。我真诚地感谢詹姆斯·卡泽对他的怀疑,我真诚地感谢洛基阿斯塔里为我设置了straignt。

Mea culpa. The C library will invoke the callback function assuming the C application binary interface. A function with C++ linkage may use a different ABI than the C ABI. This is why it is required to use a function with extern "C" linkage when passing to a callback function to a C library. My sincere apologies to James Kanze for doubting him, and my sincere thanks to Loki Astari for setting me straignt.

这篇关于转换为void *以将对象传递给cthread中的pthread的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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