多线程信号量的使用

来源:互联网 发布:惠州网络问政网站 编辑:程序博客网 时间:2024/06/03 05:02

公司业务上写了一个小模块,其中有一个功能是需要等待一个线程执行完一个函数之后,在另一个线程做出反应。

之前自己的写法是使用一个循环不断的去监视一个标志值,当标志值变化时候,代表执行完毕。但是这么做的话有一些缺陷,一个是不Sleep的话,那么占用很高的CPU使用率,显然不可行。Sleep的话,则该模块效率提不上来,就算是仅仅1MS,那么模块的速率就降到了一秒100以内了,是不可以被接受的。

陷入这种囧境还是由于自己知识水平限制,在多线程方面积累不足。

后在指导下找到了使用信号量的办法进行多线程的同步工作。

    int nRet = MsgQueue_SendNoBlock(pMPRemoteClient->pMsgSend, pMpRemoteSend);    if (nRet != ERR_SUCCESS)    {        NG_free(pMpRemoteSend);        return MP_ERR_FAILED;    }    //等待事件    NG_WaitEvent(pMPRemoteClient->phSlaveEvent[nThreadNo]);    NGtimeEnd = NGClock_GetTicks();    if (NGClock_TimeDiff(NGtimeEnd, NGtimeBegin) >=         pMPRemoteClient->piFuncTimeMs[nFuncId])    {        return MP_ERR_SEND_TIMEOUT;    }    if (pMPRemoteClient->pDataSlaveFlag[nThreadNo] == iDataSlaveFlag)    {        return MP_ERR_SUCCESS;    }

void NG_WaitEvent( HANDLE hEvent ){    MCAPI_EVENT *pEvent ;    REAL_HANDLE *pHandle ;    pHandle = (REAL_HANDLE *)hEvent;    if ( pHandle == NULL || pHandle->nId != HANDLE_ID_NGEVENT )    {        return;    }    pEvent = (MCAPI_EVENT *)(pHandle-> pObject);    ( void)sem_wait (&(pEvent-> sem));//这里会自动等到该值大于0后减去1    return;}void NG_SendEvent( HANDLE hEvent ) {    MCAPI_EVENT *pEvent ;    REAL_HANDLE *pHandle ;    pHandle = (REAL_HANDLE *)hEvent;    if ( pHandle == NULL || pHandle->nId != HANDLE_ID_NGEVENT )    {        return;    }    pEvent = (MCAPI_EVENT *)(pHandle-> pObject);    ( void)sem_post (&(pEvent-> sem));// 这里信号量加1    return;}
上面代码的两个模块,SendEvent WaitEvent实际上是对Linux信号函数的封装。

主要是下面几个函数,用于多线程同步。使用信号量,能在一个线程等待另一个线程完成某项工作,然后继续进行工作。

于是工作上的小难点被突破了。

改用信号量之后,程序在效率和性能方面大幅度提升了。

int sem_init(sem_t *sem,int pshared,unsigned int value); int sem_destroy(sem_t *sem); int sem_wait(sem_t *sem); int sem_trywait(sem_t *sem); int sem_post(sem_t *sem); int sem_getvalue(sem_t *sem); 


0 0
原创粉丝点击