美文网首页
C++ 开启线程 pthread_create 报错

C++ 开启线程 pthread_create 报错

作者: JamFF | 来源:发表于2019-06-27 17:05 被阅读0次

开启线程

头文件中,定义一个 MyFFmpeg 类:

class MyFFmpeg {

public:

    MyFFmpeg(JavaCallHelper *javaCallHelper, const char *dataSource);

    ~MyFFmpeg();

private:

    pthread_t pid_prepare;// FFmpeg初始化线程
    char *url;// 播放地址
    JavaCallHelper *pJavaCallHelper;// 回调Java层的接口

    void *prepareFFmpeg(void *args);// 线程函数
};

实现类中,开启线程的代码:

/**
 * 被子线程调用的指针函数
 */
void *MyFFmpeg::prepareFFmpeg(void *args) {
    ...省略
    return nullptr;
}

void MyFFmpeg::prepare() {
    // 参数1:线程id
    // 参数2:线程的属性,nullptr 默认属性
    // 参数3:线程创建之后执行的函数,函数指针
    // 参数4:参数3函数接受的参数
    pthread_create(&pid_prepare, nullptr, prepareFFmpeg, nullptr);
}

上面这种的写法,在编译时期就会报错,错误日志:

error: reference to non-static member function must be called
    pthread_create(&pid_prepare, nullptr, prepareFFmpeg, nullptr);
                                          ^~~~~~~~~~~~~

解决方式

error: reference to non-static member function must be called
这个日志的大概意思是:你引用(调用)了非静态函数。

方式一:

按照错误提示,将 prepareFFmpeg 定义为静态函数即可解决该问题。

class MyFFmpeg {

public:

    MyFFmpeg(JavaCallHelper *javaCallHelper, const char *dataSource);

    ~MyFFmpeg();

private:

    pthread_t pid_prepare;// FFmpeg初始化线程
    char *url;// 播放地址
    JavaCallHelper *pJavaCallHelper;// 回调Java层的接口

    static void *prepareFFmpeg(void *args);// 线程函数
};

但是存在一个问题,静态函数不能访问非静态成员,我需要在 prepareFFmpeg 函数中访问 MyFFmpeg 中的非静态成员,如果全部改为静态,很不优雅,所以推荐使用方式二。

方式二:

  1. 头文件中,在 MyFFmpeg 类内部创建新的成员函数 prepareFFmpeg
    这样的优势在于,可以方便的使用 MyFFmpeg 的成员变量。
class MyFFmpeg {

public:

    MyFFmpeg(JavaCallHelper *javaCallHelper, const char *dataSource);

    ~MyFFmpeg();

    void prepareFFmpeg();

private:

    pthread_t pid_prepare;// FFmpeg初始化线程
    char *url;// 播放地址
    JavaCallHelper *pJavaCallHelper;// 回调Java层的接口
};
  1. 实现类中,prepareFFmpeg 内部的逻辑还是之前的内容。
void MyFFmpeg::prepareFFmpeg() {
    ...省略
}
  1. 实现类中,将原先的 prepareFFmpeg 封装为全局函数 prepareFFmpeg_,提供给线程调用。
/**
 * 被子线程调用的指针函数
 */
void *prepareFFmpeg_(void *args) {
    auto *pFFmpeg = static_cast<MyFFmpeg *>(args);
    // 内部调用MyFFmpeg的成员函数
    pFFmpeg->prepareFFmpeg();
    return nullptr;
}
  1. 实现类中,开启线程。
void MyFFmpeg::prepare() {
    // 最后参数
    pthread_create(&pid_prepare, nullptr, prepareFFmpeg_, this);
}

完成,解决问题!

相关文章

网友评论

      本文标题:C++ 开启线程 pthread_create 报错

      本文链接:https://www.haomeiwen.com/subject/aczlcctx.html