pjsip如何支持多线程和巨坑
话不多说,先上代码,坑在后头
#define PJ_AUTOCONF 1
#define PJ_IS_BIG_ENDIAN 0
#define PJ_IS_LITTLE_ENDIAN 1
#define PJMEDIA_VIDEO_DEV_HAS_V4L2 1
#include <pjlib.h>
#include <pjmedia.h>
#include <pjsua.h>
#include <pjlib-util.h>
#include <pjlib.h>
#include <pjmedia/mem_port.h>
// 线程注册
static pj_status_t pjcall_thread_register(pj_thread_desc &desc)
{
pj_thread_t* thread = 0;
if (!pj_thread_is_registered()) // 判断此线程是否已添加
{
return pj_thread_register(NULL, desc, &thread);
}
return PJ_SUCCESS;
}
// 假设其他线程调用此函数
int thread1()
{
{
pj_thread_desc desc;// 要进行的操作必须再desc的生存空间内
pjcall_thread_register(desc);
/ 这里进行库操作
}
{
// 这里进行pjsip库操作会断言,提示线程未注册
}
return 0;
}
巨坑,巨坑
pj_thread_register 函数原型如下,在使用的时候要格外注意,不是所有线程都可以肆无忌惮地调用,需要满足几个条件才行,如下
/**
* Register a thread that was created by external or native API to PJLIB.
* This function must be called in the context of the thread being registered.
* When the thread is created by external function or API call,
* it must be 'registered' to PJLIB using pj_thread_register(), so that it can
* cooperate with PJLIB's framework. During registration, some data needs to
* be maintained, and this data must remain available during the thread's
* lifetime.
*
* @param thread_name The optional name to be assigned to the thread.
* @param desc Thread descriptor, which must be available throughout
* the lifetime of the thread.
* @param thread Pointer to hold the created thread handle.
*
* @return PJ_SUCCESS on success, or the error code.
*/
PJ_DECL(pj_status_t) pj_thread_register ( const char *thread_name,
pj_thread_desc desc,
pj_thread_t **thread);
/*
* 使用条件,必须满足其一
* 1.调用线程为创建了线程池的线程,一般情况下是发起会话的线程
* 2.此线程是由pjsip库中pj_thread_create()所创建的线程
* 3.此线程永远不会退出,直到程序结束(程序退出时也会段错误,但是既然程序都退了,崩不崩都一样)
*/
踩坑点
千万千万不要在临时线程中使用线程注册,不然在线程退出时会直接段错误,让你查不到原因;原因大概是此线程已经注册到pjsip的线程池中了,有些资源pjsip还在使用,然后线程退出时会回收资源,然后就崩溃了.不知道是不是这个原因,望解惑