在我的C++程序中,我使用lio_listio
調用一次發送很多(多達幾百)個寫請求。之後,我做了一些計算,當我完成後,我需要等待所有未完成的請求完成,然後才能提交下一批請求。我怎樣才能做到這一點?lio_listio:如何等待所有請求完成?
現在,我只是在一個循環中調用aio_suspend
,每次調用一個請求,但這看起來很難看。看起來我應該使用lio_listio
的struct sigevent *sevp
參數。我目前的猜測是我應該這樣做:
- 在主線程中,創建一個互斥鎖並在鎖定之前調用
lio_listio
。 - 在對
lio_listio
的調用中,指定解鎖此互斥鎖的通知函數/信號處理函數。
這應該給我想要的行爲,但它會工作可靠嗎?是否允許從信號處理程序上下文中操作互斥鎖?我讀到pthread互斥鎖可以提供錯誤檢測,並且如果您嘗試再次從同一個線程鎖定它們或從不同線程解鎖它們,將會失敗,但此解決方案依賴於死鎖。
實施例代碼,用一個信號處理程序:
void notify(int, siginfo_t *info, void *) {
pthread_mutex_unlock((pthread_mutex_t *) info->si_value);
}
void output() {
pthread_mutex_t iomutex = PTHREAD_MUTEX_INITIALIZER;
struct sigaction act;
memset(&act, 0, sizeof(struct sigaction));
act.sa_sigaction = ¬ify;
act.sa_flags = SA_SIGINFO;
sigaction(SIGUSR1, &act, NULL);
for (...) {
pthread_mutex_lock(&iomutex);
// do some calculations here...
struct aiocb *cblist[];
int cbno;
// set up the aio request list - omitted
struct sigevent sev;
memset(&sev, 0, sizeof(struct sigevent));
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGUSR1;
sev.sigev_value.sival_ptr = &iomutex;
lio_listio(LIO_NOWAIT, cblist, cbno, &sev);
}
// ensure that the last queued operation completes
// before this function returns
pthread_mutex_lock(&iomutex);
pthread_mutex_unlock(&iomutex);
}
實施例代碼,用通知功能 - 可能效率較低,因爲額外的線程被創建:
void output() {
pthread_mutex_t iomutex = PTHREAD_MUTEX_INITIALIZER;
for (...) {
pthread_mutex_lock(&iomutex);
// do some calculations here...
struct aiocb *cblist[];
int cbno;
// set up the aio request list - omitted
struct sigevent sev;
memset(&sev, 0, sizeof(struct sigevent));
sev.sigev_notify = SIGEV_THREAD;
sev_sigev_notify_function = &pthread_mutex_unlock;
sev.sigev_value.sival_ptr = &iomutex;
lio_listio(LIO_NOWAIT, cblist, cbno, &sev);
}
// ensure that the last queued operation completes
// before this function returns
pthread_mutex_lock(&iomutex);
pthread_mutex_unlock(&iomutex);
}
感謝您提供一篇非常翔實的文章。每個循環的同步都是我想要的,因爲我使用類似於雙緩衝區的東西來存儲計算的數據 - 如果互斥解決方案沒有其他問題,那麼對於我的目的應該沒問題。 我沒有意識到lio_listio()的這些限制 - 我將研究是否使用'mmap'ed文件會更好。 – 2013-02-11 01:15:39
是的,在這種情況下,我會想象你的解決方案與互斥工作正常。我唯一擔心的是在信號處理程序中釋放互斥體的模式,可能在當前阻塞獲取鎖的線程上(對於信號處理程序安全的系統調用列表:http:// pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html#tag_02_04_03)。您在使用傳統信號量的模式中使用互斥鎖。 – Arvid 2013-02-11 01:53:42
確實,它看起來像pthread_mutex_ *函數不是異步信號安全的,而sem_post是。 – 2013-02-11 19:50:45