Π‘ΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅ ΠΏΠΎΡΠΎΠΊΠΎΠ² β ΡΡΠΎ Π½Π°ΡΡΠΎΠ»ΡΠΊΠΎ Π³ΠΈΠ±ΠΊΠΈΠΉ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌ, ΡΡΠΎ ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ ΡΠ°ΠΈΡΡ Π² ΡΠ΅Π±Π΅ ΠΈ Π΄ΡΡΠ³ΠΈΠ΅, Π΅ΡΠ΅ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΠ΅ ΡΠ΅Ρ Π½ΠΈΠΊΠΈ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΡ.
ΠΠ΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΡ Π²ΡΠ·ΠΎΠ²ΠΎΠ² Π² ΠΏΠΎΡΠΎΠΊΠΎΠ²ΠΎΠΉ ΡΡΠ΅Π΄Π΅
Π Π°ΡΡΠΌΠΎΡΡΠ΅Π² Β«Π² ΠΏΠ΅ΡΠ²ΠΎΠΌ ΠΏΡΠΈΠ±Π»ΠΈΠΆΠ΅Π½ΠΈΠΈΒ» ΡΠ΅Ρ Π½ΠΈΠΊΡ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΡ Π΄Π°Π½Π½ΡΡ ΠΏΠΎΡΠΎΠΊΠΎΠ², ΠΌΡ ΡΠ΅ΠΏΠ΅ΡΡ Π³ΠΎΡΠΎΠ²Ρ ΠΎΡΠ²Π΅ΡΠΈΡΡ Π½Π° Π²ΠΎΠΏΡΠΎΡ: Β«Π ΡΠ΅ΠΌ ΠΆΠ΅ Π³Π»Π°Π²Π½ΠΎΠ΅ ΠΏΡΠ΅Π΄Π½Π°Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΠ°ΠΊΠΎΠΉ Π² ΠΎΠ±ΡΠ΅ΠΌ-ΡΠΎ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ Π³ΡΠΎΠΌΠΎΠ·Π΄ΠΊΠΎΠΉ ΡΠ΅Ρ Π½ΠΈΠΊΠΈ? Π Π·Π°ΡΠ΅ΠΌ Π΄Π»Ρ Π΅Π΅ Π²Π²Π΅Π΄Π΅Π½ΠΈΡ ΠΏΠΎΡΡΠ΅Π±ΠΎΠ²Π°Π»ΠΎΡΡ ΡΠΏΠ΅ΡΠΈΠ°Π»ΡΠ½ΠΎ ΡΠ°ΡΡΠΈΡΡΡΡ ΡΡΠ°Π½Π΄Π°ΡΡΡ POSIX?Β» Π‘Π°ΠΌΠΎΠ΅ ΠΏΡΡΠΌΠΎΠ΅ Π΅Π΅ ΠΏΡΠ΅Π΄Π½Π°Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅, ΠΏΠΎΠΌΠΈΠΌΠΎ Π΄ΡΡΠ³ΠΈΡ Β«ΠΏΠΎΠΏΡΡΠ½ΡΡ Β» ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠΉ, ΠΊΠΎΡΠΎΡΡΠ΅ Π±ΡΠ»ΠΈ ΠΎΠ±ΡΡΠΆΠ΄Π΅Π½Ρ ΡΠ°Π½Π΅Π΅,Β β ΡΡΠΎ ΠΎΠ±ΡΠΈΠΉ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌ ΠΏΡΠ΅Π²ΡΠ°ΡΠ΅Π½ΠΈΡ ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠ΅ΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ Π΄Π»Ρ ΠΎΠ΄Π½ΠΎΠΏΠΎΡΠΎΠΊΠΎΠ²ΠΎΠ³ΠΎ ΠΈΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ Π² ΡΡΠ½ΠΊΡΠΈΡ, Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΡΡ (thread safe) Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡΠΎΡΠ½ΠΎΠΌ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΠΈ. ΠΡΠΎΡ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌ ΠΏΡΠ΅Π΄Π»Π°Π³Π°Π΅Ρ Π΅Π΄ΠΈΠ½ΡΡ (Π² ΡΠΌΡΡΠ»Π΅ Β«Π΅Π΄ΠΈΠ½ΠΎΠΎΠ±ΡΠ°Π·Π½ΡΡΒ», Π° Π½Π΅ Β«Π΅Π΄ΠΈΠ½ΡΡΠ²Π΅Π½Π½ΠΎ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΡΡΒ») ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΡ Π΄Π»Ρ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠ² Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΡΠ½ΡΡ ΠΌΠΎΠ΄ΡΠ»Π΅ΠΉ.
ΠΠ‘ QNX, Π·Π°ΠΈΠΌΡΡΠ²ΡΡΡΠ°Ρ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠ°ΡΠΈΠΉ GNU-ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ (gcc, make, β¦), ΠΏΡΠ΅Π΄ΡΡΠΌΠ°ΡΡΠΈΠ²Π°Π΅Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΏΠΎΡΡΡΠΎΠ΅Π½ΠΈΡ ΠΊΠ°ΠΊ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΡΠ²ΡΠ·ΡΠ²Π°Π΅ΠΌΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊ (ΠΈΠΌΠ΅Π½Π° ΡΠ°ΠΉΠ»ΠΎΠ² Π²ΠΈΠ΄Π°
xxx.axxx.soxxx.ΠΎΠΡΠ»ΠΈ ΠΌΡ ΠΎΠ±ΡΠ°ΡΠΈΠΌΡΡ ΠΊ ΡΠ΅Ρ Π½ΠΈΡΠ΅ΡΠΊΠΎΠΉ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΠΈ API QNX (Π°Π½Π°Π»ΠΎΠ³ΠΈΡΠ½Π°Ρ ΠΊΠ°ΡΡΠΈΠ½Π° Π±ΡΠ΄Π΅Ρ ΠΈ Π² API Π»ΡΠ±ΠΎΠ³ΠΎ UNIX), ΡΠΎ Π·Π°ΠΌΠ΅ΡΠΈΠΌ, ΡΡΠΎ ΡΠΎΠ»ΡΠΊΠΎ Π½Π΅Π±ΠΎΠ»ΡΡΠ°Ρ ΡΠ°ΡΡΡ ΡΡΠ½ΠΊΡΠΈΠΉ ΠΎΡΠΌΠ΅ΡΠ΅Π½Π° ΠΊΠ°ΠΊ thread safe. Π Β«Π½Π΅Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΡΠΌΒ» ΠΎΡΠ½Π΅ΡΠ΅Π½Ρ ΡΠ°ΠΊΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΈΠ·Π²Π΅ΡΡΠ½ΡΠ΅ Π²ΡΠ·ΠΎΠ²Ρ, ΠΊΠ°ΠΊ
select()rand()readln()*_rMsgSend()MsgSend_r()Π ΡΠ΅ΠΌ ΠΆΠ΅ ΡΠΎΡΡΠΎΠΈΡ Π½Π΅Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΡ Π² ΠΏΠΎΡΠΎΠΊΠΎΠ²ΠΎΠΉ ΡΡΠ΅Π΄Π΅? Π Π½Π΅ΡΠ΅Π΅Π½ΡΠ΅ΡΠ°Π±Π΅Π»ΡΠ½ΠΎΡΡΠΈ ΡΡΠ½ΠΊΡΠΈΠΉ, ΠΏΠΎΠ΄Π³ΠΎΡΠΎΠ²Π»Π΅Π½Π½ΡΡ Π΄Π»Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ Π² ΠΎΠ΄Π½ΠΎΠΏΠΎΡΠΎΡΠ½ΠΎΠΉ ΡΡΠ΅Π΄Π΅, Π² ΠΏΠ΅ΡΠ²ΡΡ ΠΎΡΠ΅ΡΠ΅Π΄Ρ ΡΠ²ΡΠ·Π°Π½Π½ΠΎΠΉ Ρ ΠΏΠΎΡΡΠ΅Π±Π½ΠΎΡΡΡΡ Π² ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΡ Π΄Π°Π½Π½ΡΡ , Ρ ΡΠ°Π½ΡΡΠΈΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΎΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π²ΡΠ·ΠΎΠ²Π° ΠΊ Π΄ΡΡΠ³ΠΎΠΌΡ. Π Π°ΡΡΠΌΠΎΡΡΠΈΠΌ ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΡΡ ΡΡΠ½ΠΊΡΠΈΡ
rand()ΠΠΠ‘
int rand(void) {
Β static int x = rand_init();
Β return x = (A*x + B)%C;
}Π’Π°ΠΊΠ°Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ, ΡΠΎΠ²Π΅ΡΡΠ΅Π½Π½ΠΎ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½Π°Ρ Π² ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΠΉ (ΠΎΠ΄Π½ΠΎΠΏΠΎΡΠΎΠΊΠΎΠ²ΠΎΠΉ) ΠΌΠΎΠ΄Π΅Π»ΠΈ, ΡΡΠ°Π½ΠΎΠ²ΠΈΡΡΡ Π½Π΅Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΠΉ Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡΠΎΡΠ½ΠΎΠΉ: Π°) Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΠ΅
xrand()xx1. ΠΠ·ΠΌΠ΅Π½ΠΈΡΡ ΠΏΡΠΎΡΠΎΡΠΈΠΏ ΠΎΠ±ΡΡΠ²Π»Π΅Π½ΠΈΡ ΡΡΠ½ΠΊΡΠΈΠΈ:
int rand_r(int *x) {
Β return x = (Π * (*x) + Π) % Π‘;
};ΠΡΠΈ ΡΡΠΎΠΌ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ° Β«ΠΊΠ»ΠΎΠ½ΠΈΡΠΎΠ²Π°Π½ΠΈΡΒ» ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ x Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΈΠ· ΠΏΠΎΡΠΎΠΊΠΎΠ² (Π΄Π° ΠΈ Π½Π°ΡΠ°Π»ΡΠ½ΠΎΠΉ Π΅Π΅ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ) Π½Π΅ ΡΠ½ΠΈΠΌΠ°Π΅ΡΡΡ, ΠΎΠ½Π° ΡΠΎΠ»ΡΠΊΠΎ ΠΏΠ΅ΡΠ΅Π½ΠΎΡΠΈΡΡΡ Π½Π° ΠΏΠ»Π΅ΡΠΈ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ, ΡΡΠΎ, ΠΎΠ΄Π½Π°ΠΊΠΎ, Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ ΠΏΡΠΎΡΡΠΎ ΡΠ΅ΡΠ°Π΅ΡΡΡ ΠΏΡΠΈ ΡΠΎΠ·Π΄Π°Π½ΠΈΠΈ ΠΏΠΎΡΠΎΠΊΠΎΠ²ΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ Π·Π° ΡΡΠ΅Ρ Π΅Π΅ ΡΡΠ΅ΠΊΠ° Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ :
void* thrfunc(void*) {
Β int x = rand_init();
Β ... = rand_r(&x);
};ΠΠΌΠ΅Π½Π½ΠΎ ΡΠ°ΠΊΠΎΠ²Π° ΡΠΎΡΠΌΠ° ΠΈ ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡΠΎΡΠ½ΠΎΠ³ΠΎ ΡΠΊΠ²ΠΈΠ²Π°Π»Π΅Π½ΡΠ° Π² API QNX β
rand_r()2. Π ΡΡΠΎΠΌ Π²Π°ΡΠΈΠ°Π½ΡΠ΅ ΠΌΡ ΡΠΎΡ ΡΠ°Π½ΡΠ΅ΠΌ ΠΏΡΠΎΡΠΎΡΠΈΠΏ ΠΎΠΏΠΈΡΠ°Π½ΠΈΡ ΡΡΠ½ΠΊΡΠΈΠΈ Π±Π΅Π· ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Π·Π° ΡΡΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΡΠ°Π·Π»ΠΈΡΠ½ΡΡ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠΎΠ² ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΡ Π΄Π°Π½Π½ΡΡ ΠΏΠΎΡΠΎΠΊΠ°. (ΠΠ΅ΡΡ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½Π½ΡΠΉ Π½ΠΈΠΆΠ΅ ΠΊΠΎΠ΄ ΡΠ°Π·ΠΌΠ΅ΡΠ΅Π½ Π² ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎΠΉ Π΅Π΄ΠΈΠ½ΠΈΡΠ΅ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ; Π²ΡΠ΅ ΠΈΠΌΠ΅Π½Π°, Π·Π° ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ΠΌ
rand()static
static pthread_key_t key;
static pthread_once_t once = PTHREAD_ONCE_INIT;
static void destr(void* db) { delete x; }
static void once_creator(void) { pthread_key_create(&key, destr); }
int rand(void) {
Β pthread_once(&once, once_creator);
Β int *x = pthread_getspecific(key);
Β if (x == NULL) {
Β pthread_setspecific(key, x = new int);
Β *x = rand_init();
Β }
Β return x = (A * (*x) + B) % C;
}Π ΡΡΠΎΠΌ Π²Π°ΡΠΈΠ°Π½ΡΠ΅, Π² ΠΎΡΠ»ΠΈΡΠΈΠ΅ ΠΎΡ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅Π³ΠΎ, Π²Π΅ΡΡ ΠΊΠΎΠ΄ Π²ΡΠ·ΡΠ²Π°ΡΡΠ΅Π³ΠΎ ΡΡΠ°Π³ΠΌΠ΅Π½ΡΠ° ΠΏΡΠΈ ΠΏΠ΅ΡΠ΅Ρ ΠΎΠ΄Π΅ ΠΊ ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡΠΎΡΠ½ΠΎΠΉ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΎΡΡΠ°Π΅ΡΡΡ ΡΠ΅ΠΊΡΡΡΠ°Π»ΡΠ½ΠΎ Π½Π΅ΠΈΠ·ΠΌΠ΅Π½Π½ΡΠΌ:
void* thrfunc(void*) {
Β // ...
Β while (true) {
Β ... = rand(x);
Β }
}ΠΠ΅ΡΠ΅Π²ΠΎΠ΄ Π²ΡΠ΅Π³ΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΠΎΠ³ΠΎ ΠΏΡΠΎΠ΅ΠΊΡΠ° Π½Π° ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠΎΡΠΎΠΊΠΎΠ²ΠΎΠΉ ΡΡΠ΅Π΄Ρ ΡΠΎΡΡΠΎΠΈΡ Π² Π·Π°ΠΌΠ΅Π½Π΅ ΠΎΠ±ΡΠ΅ΠΊΡΠ½ΠΎΠΉ Π΅Π΄ΠΈΠ½ΠΈΡΡ (ΠΎΠ±ΡΠ΅ΠΊΡΠ½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π°, Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ), ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠ΅ΠΉ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ
rand()ΠΡΠΈ ΡΠ°ΠΊΠΎΠΌ ΡΠΏΠΎΡΠΎΠ±Π΅ ΠΈΠ·ΠΌΠ΅Π½ΡΡΡΡΡ ΠΏΠΎΠ΄ ΠΏΠΎΡΠΎΠΊΠΎΠ²ΡΡ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΡ ΠΈ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΠ΅ ΠΎΠ±ΡΠ΅ΠΈΠ·Π²Π΅ΡΡΠ½ΡΠ΅ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΡΠ½ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ API, Π½Π°ΠΏΠΈΡΠ°Π½Π½ΡΠ΅ Π² ΡΠ²ΠΎΠ΅ΠΌ ΠΏΠ΅ΡΠ²ΠΎΠ·Π΄Π°Π½Π½ΠΎΠΌ Π²ΠΈΠ΄Π΅ 25 Π»Π΅Ρ Π½Π°Π·Π°Π΄β¦ (ΠΏΠΎ ΠΊΡΠ°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅ΡΠ΅, ΡΠ°ΠΊ ΠΏΡΠ΅Π΄Π»Π°Π³Π°Π΅Ρ ΡΡΠΎ Π΄Π΅Π»Π°ΡΡ ΡΡΠ°Π½Π΄Π°ΡΡ POSIX, Π²Π²ΠΎΠ΄ΡΡΠΈΠΉ Π² ΠΎΠ±ΠΈΡ ΠΎΠ΄ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅ ΠΏΠΎΡΠΎΠΊΠΎΠ²).
ΠΠΈΡΠΏΠ΅ΡΡΠ΅ΡΠΈΠ·Π°ΡΠΈΡ ΠΏΠΎΡΠΎΠΊΠΎΠ²
ΠΠ°ΠΆΠ΄ΠΎΠΌΡ ΠΏΠΎΡΠΎΠΊΡ, ΡΡΠ°ΡΡΠ²ΡΡΡΠ΅ΠΌΡ Π² ΠΏΡΠΎΡΠ΅ΡΡΠ΅ Π΄ΠΈΡΠΏΠ΅ΡΡΠ΅ΡΠΈΠ·Π°ΡΠΈΠΈ, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΠ΅Ρ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ ΡΡΡΡΠΊΡΡΡΡ, ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΉ Π² ΡΠ°ΠΉΠ»Π΅
<sys/target_nto.h>
struct sched_param {