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...