2012-09-28 66 views
4

我正在使用read (2)從文件(/dev/random,其中數據到達非常緩慢)進行讀取。禁止Linux讀取(2),直到所有計數字節到達

但是,read()僅在讀取幾個字節後返回,而我希望它等到指定的字節數已被讀取(或發生錯誤),因此返回值應始終爲count ,或-1。

有什麼辦法可以實現這種行爲嗎? open (2)read (2)手冊不包含任何有關該主題的有用信息,也沒有在因特網上找到任何有關該主題的信息。

我完全瞭解將read()放在while循環內並調用它直到讀取所有數據爲止的解決方法。我只想知道這是否能夠以一種恰當的方式實現,從而產生確定性行爲,並且只涉及O(1)系統調用,而不是在while循環解決方案中的非確定性O(n)。

下面的最小例子重現了這個問題。

#include <stdio.h> 

#include <unistd.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 

int main() { 
     int fd = open("/dev/random", 0); 

     char buf[128]; 
     size_t bytes = read(fd, buf, sizeof(buf)); 

     printf("Bytes read: %lu\n", bytes); //output is random, usually 8. 

     close(fd); 
} 

回答

3

雖然在接收到請求的數據之前,讀取信號可能會被信號中斷,但在沒有時間的情況下無法真正完成讀取。

不幸的是,你必須檢查返回值和計數字節。 是的,最簡單的方法是編寫一個包裝函數。

+0

+1,因爲這是'/ dev/random'反正...一些額外的讀取電話不會減慢任何。 – FatalError

0

從文檔中,/ dev/random盡最大努力返回最可靠的隨機數據,並且限制了它在一次讀取中返回的字節數。

但是讀取/ dev/urandom(注意'u')會返回儘可能多的數據(緩衝區大小),有時候數據會少一些隨機數。

這裏是an useful link

關於閱讀()行爲,我很肯定,這不能改變:read()返回的數據量底層plumbery(例如磁盤+驅動+ ...)決定返回,這是一個設計行爲。正如你所說,做事的方式是循環直到你收到儘可能多的數據。

+0

這可靠嗎? 'read'可以被信號中斷,信號源的類型是否保證在呼叫結束之前沒有這樣的信號會到達? –

+0

我需要真正的隨機數據。另外,我不認爲''dev/urandom''的讀取總是會讀取'count'字節,這可能性更大。 –

+0

我認爲是的,它是有保證的。無論如何,如果你想讓數據儘可能隨機,你必須使用/ dev/random AND循環,直到達到你想要的字節數。我很抱歉,但我真的認爲你不能強制read()返回儘可能多的數據。 – mbarthelemy

3

正如大家所說,

  • 有沒有辦法保證128個字節的隨機性是你讀返回前可用,

  • 同時參與獲得八個字節的開銷與生成八個字節的分期成本相比,這是微不足道的;因此,

  • 你應該記住,熵值得花費巨大,並在消耗時考慮到這一點。

儘管如此,沒有回答這個問題將是不完整提的是,在man 4 random(上依稀最近的Linux發行版),你應該找到以下信息:

The files in the directory /proc/sys/kernel/random 
(present since 2.3.16) provide an additional interface 
to the /dev/random device. 

...

The file read_wakeup_threshold contains the number of bits of 
entropy required for waking up processes that sleep waiting 
for entropy from /dev/random. The default is 64. 

即,64比特,這是八個字節。有了超級用戶權限,你可以增加這個值,但是imho增加到1024,然後期望你的機器保持正常工作可能是非常樂觀的。我不知道所有想要一點熵的東西,但我一定注意到,我的熵池升降,所以我知道一些東西需要它,我強烈懷疑,無論什麼東西是不會很高興必須等待它的1024位可用。無論如何,你知道有一點繩子...

相關問題