1 问题描述 在移植中间件过程中,在SylixOS下调用pthread_join时,如果线程在pthread_join等待之前结束,则线程返回无效线程错误值。在Linux下这种调用会正常返回。两种实现是有差别的,实现的原理分别如下。 2 pthread_join函数的实现机制 2.1 SylixOS实现机制 在SylixOS下调用pthread_join时,如果线程在pthread_join等待之前结束,线程返回无效线程错误标志,具体实现如程序清单 2.1所示。函数在实现中会先检测线程是否有效,如果线程无效则直接返回线程无效的错误。 程序清单 2.1 SylixOS pthread_join实现机制 LW_API ULONG API_ThreadJoin (LW_OBJECT_HANDLE ulId, PVOID *ppvRetValAddr) { REGISTER UINT16 usIndex; REGISTER PLW_CLASS_TCB ptcbCur; REGISTER PLW_CLASS_TCB ptcb;

usIndex = _ObjectGetIndex(ulId);

if (LW_CPU_GET_CUR_NESTING()) {   /*  不能在中断中调用            */
    _DebugHandle(__ERRORMESSAGE_LEVEL, "called from ISR.\r\n");
    _ErrorHandle(ERROR_KERNEL_IN_ISR);
    return  (ERROR_KERNEL_IN_ISR);
}

LW_TCB_GET_CUR_SAFE(ptcbCur);

#if LW_CFG_ARG_CHK_EN > 0 if (!_ObjectClassOK(ulId, _OBJECT_THREAD)) {/* 检查 ID 类型有效性 */ _ErrorHandle(ERROR_KERNEL_HANDLE_NULL); return (ERROR_KERNEL_HANDLE_NULL); }

if (_Thread_Index_Invalid(usIndex)) {    /*  检查线程有效性              */
    _ErrorHandle(ERROR_THREAD_NULL);
    return  (ERROR_THREAD_NULL);
}

#endif

__THREAD_CANCEL_POINT();       /*  测试取消点                  */

__KERNEL_ENTER();                 /*  进入内核                    */
if (_Thread_Invalid(usIndex)) {
    __KERNEL_EXIT();              /*  退出内核                    */
    _ErrorHandle(ERROR_THREAD_NULL);
    return  (ERROR_THREAD_NULL);
}

ptcb = _K_ptcbTCBIdTable[usIndex];

if (ptcb == ptcbCur) {          /*  不能阻塞自己                */
    __KERNEL_EXIT();             /*  退出内核                    */
    _DebugHandle(__ERRORMESSAGE_LEVEL, "thread join self.\r\n");
    _ErrorHandle(ERROR_THREAD_JOIN_SELF);
    return  (ERROR_THREAD_JOIN_SELF);
}
    
if (ptcb->TCB_bDetachFlag) {
    __KERNEL_EXIT();             /*  退出内核                    */
    _ErrorHandle(ERROR_THREAD_DETACHED);
    return  (ERROR_THREAD_DETACHED);
}

_ThreadJoin(ptcb, ppvRetValAddr);   /*  合并                        */

__KERNEL_EXIT();                       /*  退出内核                    */

return  (ERROR_NONE);

}

2.2 Linux实现机制 在Linux下如果在调用pthread_join前线程已经退出,则返回正常值。在中间件移植过程中针对pthread_join的测试用例会可能出现问题,此时如果线程结束后调用pthread_join在SylixOS下会出现问题,而在Linux是正常,需要屏蔽该类型的用例。