rand srand的實現機制

2021-06-09 01:59:28 字數 1647 閱讀 8302

rand和srand是用於產生偽隨機數的兩個函式,根據參考手冊rand的返回值是在[0, rand_max]之間的資料,rand_max在不同的系統中數值有所不同。

以下是rand和srand實現方式的乙個示例(假定rand_max為32767)

static unsigned long next = 1;

/* rand_max assumed to be 32767 */

int rand(void)

void srand(unsigned seed)

事實上現在多數系統上的rand和srand就是使用的這種機制,只是上面取的數字或略有不同。

#include #include int main()

getchar();

return 0;

}

在windows下編譯上面這個程式並執行,它產生的隨機序列是:

41 18467 6334 26500 19169 15724 11478 29358 26962 24464

但是,當我們再執行一次時,我們會發現產生的序列是相同的。在當我們需要每次執行都產生不同的序列時,上面這樣的函式顯然是不行的。這是要注意的第乙個陷阱。

在linux下編譯上面的程式,兩次執行也會得出相同的結果,這與我們程式**的預期是相同的。如果我們在程式的迴圈之前新增srand(1),我們會得到相同的序列(與不呼叫srand效果相同)

根據實現機制給出的**,如果我們寫的程式是如下:

#include #include int main()

getchar();

return 0;

}

那它輸出的序列將是相同的數,經過實際測試,確實如此:

41 41 41 41 41 41 41 41 41 41

如何寫出每次執行結果都不同的隨機序列呢?我們來看下例:

#include #include #include int main()

getchar();

return 0;

}

上面的**,取了當前時間作為隨機數種子,所以每隔一秒鐘重新執行程式產生的序列都是不同的,但在同一秒鐘會產生相同的序列,這不太理想。而且雖然每一秒的序列有所不同,但每個序列第乙個數的數值往往相差不大,這不適用於一些要求比較嚴格的場合。

所以在這種情況下,最好用能取到毫秒和微秒級系統時間的函式去改寫上面程式,並且在取到數時,先取一次模,再將數字拿去做種子會比較可靠一些。

如下面在linux下的乙個實現方法:

#include #include #include #include int main()

; gettimeofday(&tv, &tz);

/* tv.tv_usec 是乙個微秒級的時間 */

seed = tv.tv_usec % 65536;

srand(seed);

for (i = 0; i < 10; i++)

getchar();

return 0;

}

這個版本的執行結果基本可以滿足預期,都是不相同的序列,即使在fork多個程序執行時,也可以使每個程序所得到的序列是不相同的。

Workqueue機制的實現

workqueue機制的實現 2012 02 05 22 18 標籤 workqueue 分類 linux裝置驅動模型 workqueue機制中定義了兩個重要的資料結構,分析如下 cpu workqueue struct結構。該結構將cpu和核心執行緒進行了繫結。在建立workqueue的過程中,l...

SPRING MVC的實現機制

spring mvc 的相關概念 dispatcherservlet 前端控制器,也是整個架構的核心,負責處理和分發請求。handleradapter 對於不同型別的控制器,該類負責把handler請求處理的結果統一轉換成modelandview。modelandview 包含資料和檢視的資訊,一般...

KVC的實現機制

kvc和kvo都屬於鍵值程式設計而且底層實現機制都是isa swizzing,所以本來想放在一起講的。但是篇幅有限所以就分成了兩篇博文 kvo實現機制傳送門 kvc概述 kvc是key value coding的簡稱。它是一種可以通過字串的名字 key 來訪問類屬性的機制。而不是通過呼叫setter...