posix訊號量sem_wait死鎖解決方法
阿新 • • 發佈:2019-01-27
在開發過程中,有三個獨立執行的程式模組,三個模組都對sqlite資料庫進行讀寫操作。sqlite在linux共享性較差,所以需要加入互斥訊號量解決三個模組訪問資料庫該問題。另外,在加入訊號量後,訊號量sem初始化為1,如果三個模組任意一個在讀或寫資料庫時ctrl+c掉(除錯過程需要),有時會造成訊號量sem保持sem_wait後的值,也就是為0;這就造成了死鎖。
為了解決上述情況,決定在某一個模組使用sem_timedwait(sem_t *sem,const struct timespec *abs_timeout)函式解決。abs_timeout 指定一個阻塞的時間上限,如果呼叫因不能立即執行遞減而要阻塞。 abs_timeout 引數指向一個指定絕對超時時刻的結構,這個結果由自
Epoch,1970-01-01 00:00:00 +0000(UTC) 秒數和納秒數構成。通過一段時間對sem值的sem_timedwait,如果能使訊號量-1,則證明訊號量正常,再post該sem訊號量,恢復sem。如果累計次數已到,仍然沒有一次使訊號量-1,則證明sem不正常,也就是為0,需要post該訊號量,恢復sem。
具體的實現程式碼如下,此為擷取的新增sem_timedwait的部分程式碼:
[cpp] view plaincopyprint?- int i = 0;
- int result;
- int k=1;
- while
- {
- struct timespec ts;
- struct timeval tt;
- gettimeofday(&tt,NULL);
- ts.tv_sec = tt.tv_sec;
- ts.tv_nsec = tt.tv_usec*1000 + k * 1000 * 1000;
- ts.tv_sec += ts.tv_nsec/(1000 * 1000 *1000);
- ts.tv_nsec %= (1000 * 1000 *1000);
- result=sem_timedwait(sem,&ts);
- if(result==0)
- {
- sem_post(sem);
- break;
- }
- if(result==-1)
- {
- printf("errno value :%d ,it means %s\n",errno,strerror(errno));
- printf("process iiii%d\n",i);
- }
- i++;
- k++;
- }
- if(i==100)
- {
- sem_post(sem);
- }
- printf("sem time wait over\n");
int i = 0;
int result;
int k=1;
while(i < 100)
{
struct timespec ts;
struct timeval tt;
gettimeofday(&tt,NULL);
ts.tv_sec = tt.tv_sec;
ts.tv_nsec = tt.tv_usec*1000 + k * 1000 * 1000;
ts.tv_sec += ts.tv_nsec/(1000 * 1000 *1000);
ts.tv_nsec %= (1000 * 1000 *1000);
result=sem_timedwait(sem,&ts);
if(result==0)
{
sem_post(sem);
break;
}
if(result==-1)
{
printf("errno value :%d ,it means %s\n",errno,strerror(errno));
printf("process iiii%d\n",i);
}
i++;
k++;
}
if(i==100)
{
sem_post(sem);
}
printf("sem time wait over\n");