在多线程下,在同一时间内,可能有多个线程在操作。如果没有同步机制,那么很难保证每个线程操作的正确性。
1、互斥锁概念:
互斥锁提供一个可以在同一时间,只让一个线程访问临界资源的的操作接口。互斥锁(Mutex)是个提供线程同步的基本锁。上锁后,其他的线程如果想要锁上,那么会被阻塞,直到锁释放后。
如果,在锁释放后,有多个线程被阻塞,那么,所有的被阻塞的线程会被设为可执行状态。第一个执行的线程,取得锁的控制权,上锁。其他的线程继续阻塞。
2、互斥锁系统原型
互斥锁的系统原型为:pthread_mutex_t,在用互斥锁之前,必须要初始化互斥锁,可以调用pthread_mutex_init;或者是PTHREAD_MUTEX_INITIALZER(仅用于静态分配内存)如果我们动态分配互斥锁(比如,用malloc),那么,在释放内存之前,必须调用pthread_mutex_destroy;
下面为互斥锁初始化和销毁的函数原型:
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr); int pthread_mutex_destroy(pthread_mutex_t *mutex); int pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t *mutex);
3、CEC处理互斥锁的使用
./aps/application/daemon/src/umf_cec.c pthread_mutex_t as_mutex; //获取锁,即初始化 void CECTV_Init(CECTV_ModualCfg_t *pCEC_ModualCfg) { CEC_t *pcec = cec_GetHandle(); if (pcec->bCECExecuted) return; pcec->menuState = MS_DEACTIVATED; pcec->LogAddr = g_pKMFShareData->CecLogAddr; pcec->inputSource = g_pKMFShareData->CecPwrOnSrc; #ifdef CONFIG_HDMI_ALL_PORT_TERMINATION_ON pcec->bActiveSrcCheck = TRUE; #endif //bCHScanStop = TRUE; //HPStatus = FALSE; CecAudioARC = FALSE; //cecHdmiPortStatus = ptv->pKMFShareData->iHDMIStatus; //bAudioModeOn = ptv->pMenuSetting->CecAudioARC; bAudioModeOn = FALSE; UmfHandler_Register(cec_CecdHandler); cecd_enable(); pcec->bCECExecuted = TRUE; pthread_mutex_init(&as_mutex, NULL); //申请锁 } //使用锁 HRESULT cec_ReportActiveSource(CEC_t *pcec, CECDMSG_NOTICECECD *pnotice) { CECTV_MessageBody_t stEvt; UMFDBG(0,"Receive %s, toSrc=%d, inputSrc=%d, LogAddr=%d, viewonState=%d ",__FUNCTION__, pnotice->toSrc, pcec->inputSource, pnotice->active_logAddr, pnotice->viewon_state); pcec->menuState = MS_DEACTIVATED; if (pcec->inputSource != pnotice->toSrc) {
if (bBlockActiveSrc) { //bBlockActiveSrc = FALSE; return S_OK; } else { bBlockActiveSrc = TRUE; pthread_mutex_lock(&as_mutex); pthread_cond_signal(&as_cond); pthread_mutex_unlock(&as_mutex); }
} }
4、NVM互斥锁 API
int Cmd_NVMInital(void) { if (gFlashWriteMutex == NULL) { GL_MutexCreate("NVMWriteMutex", &gFlashWriteMutex); if (gFlashWriteMutex == NULL) { return -1; } } return 0; } int Cmd_NVMUninital(void) { if (gFlashWriteMutex != NULL) { GL_MutexLock(gFlashWriteMutex); GL_MutexDelete(gFlashWriteMutex); gFlashWriteMutex = NULL; } return 0; } int Cmd_NVMLOCK(void) { GL_MutexLock(gFlashWriteMutex); return 0; } int Cmd_NVMUNLOCK(void) { GL_MutexUnlock(gFlashWriteMutex); return 0; }
在读写FLASH时原子操作,使用使用互斥锁
INT8 Cmd_FlashWrite(UINT32 destAddr, UINT32 srcAddr, UINT32 size) { FlashControl_t flashctrl = {0}; INT8 retval; flashctrl.op = KMF_OP_SET; flashctrl.destAddr = destAddr; flashctrl.srcAddr = srcAddr; flashctrl.size = size; GL_MutexLock(gFlashWriteMutex); retval = ioctl(kmfdev, KMF_IOC_FLASHCTRL, &flashctrl); GL_MutexUnlock(gFlashWriteMutex); return retval; }