ΠΠΎΠΌΠΈΠΌΠΎ Π°ΡΠΎΠΌΠ°ΡΠ½ΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ Π½Π°Π΄ ΡΡΠΎΠΉ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΌΠΎΠ³ΡΡ Π²ΡΠΏΠΎΠ»Π½ΡΡΡΡΡ Π»ΡΠ±ΡΠ΅ Π΄ΡΡΠ³ΠΈΠ΅ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΡΡΠΈΡΠ°ΡΡ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΡΠΌΠΈ Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡΠΎΡΠ½ΠΎΠΉ ΡΡΠ΅Π΄Π΅: ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ, ΠΏΡΠΈΡΠ²Π°ΠΈΠ²Π°Π½ΠΈΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ, ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ. ΠΠΎΠ»Π΅Π΅ ΡΠΎΠ³ΠΎ, ΠΏΡΠΈ Π²ΡΡ ΠΎΠ΄Π΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π·Π° ΠΎΠ±Π»Π°ΡΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠ³ΠΎ ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡΠΎΡΠ½ΠΎΠ³ΠΎ Π΄ΠΎΡΡΡΠΏΠ° ΠΊ ΡΡΠΎΠΉ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΎΠ½Π° ΠΌΠΎΠΆΠ΅Ρ Π΄Π°Π»Π΅Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ Π»ΡΠ±ΡΠΌ ΡΡΠ°Π΄ΠΈΡΠΈΠΎΠ½Π½ΡΠΌ ΠΈ ΠΏΡΠΈΠ²ΡΡΠ½ΡΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ.
ΠΠ°ΠΆΠ½ΠΎ ΡΠ°ΠΊΠΆΠ΅ ΠΎΡΠΌΠ΅ΡΠΈΡΡ, ΡΡΠΎ ΡΠ΅ΡΠΌΠΈΠ½ Β«Π°ΡΠΎΠΌΠ°ΡΠ½ΠΎΡΡΡΒ» ΠΎΡΠ½ΠΎΡΠΈΡΡΡ Π½Π΅ ΠΊ ΠΎΡΠΎΠ±ΡΠΌ ΡΠ²ΠΎΠΉΡΡΠ²Π°ΠΌ Π½Π΅ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠ° Π΄Π°Π½Π½ΡΡ , Π° ΠΊ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½Π½ΠΎΠΌΡ ΡΡΠ΄Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎ Π²ΡΠΏΠΎΠ»Π½ΡΡΡ Π½Π°Π΄ ΡΡΠΈΠΌ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠΌ Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡΠΎΡΠ½ΠΎΠΉ ΡΡΠ΅Π΄Π΅.
ΠΠ±ΡΠΈΠΉ Π²ΠΈΠ΄ ΠΏΡΠΎΡΠΎΡΠΈΠΏΠΎΠ² ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΈΠ· Π΄Π²ΡΡ Π³ΡΡΠΏΠΏ Π°ΡΠΎΠΌΠ°ΡΠ½ΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ:
void atomic_*(volatile unsigned *D, unsigned S);
unsigned atomic_*_value(volatile unsigned *D, unsigned S);
Π³Π΄Π΅ Π²ΠΌΠ΅ΡΡΠΎ * Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΡΡΠΎΡΡΡ ΠΈΠΌΡ ΠΎΠ΄Π½ΠΎΠΉ ΠΈΠ· ΠΏΡΡΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ (ΡΠ°ΠΊΠΈΠΌ Π°Π»Π³ΠΎΡΠΈΡΠΌΠΎΠΌ ΠΈ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°Π΅ΡΡΡ 10 ΡΠ°Π·Π»ΠΈΡΠ½ΡΡ Π°ΡΠΎΠΌΠ°ΡΠ½ΡΡ ΡΡΠ½ΠΊΡΠΈΠΉ):
add β Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΡΠΈΡΠ»Π΅Π½Π½ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΊ ΠΎΠΏΠ΅ΡΠ°Π½Π΄Ρ;
sub β Π²ΡΡΠ΅ΡΡΡ ΡΠΈΡΠ»Π΅Π½Π½ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΈΠ· ΠΎΠΏΠ΅ΡΠ°Π½Π΄Π°;
clr β ΠΎΡΠΈΡΡΠΈΡΡ Π±ΠΈΡΡ Π² Π·Π½Π°ΡΠ΅Π½ΠΈΠΈ ΠΎΠΏΠ΅ΡΠ°Π½Π΄Π° (Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ ΠΏΠΎΠ±ΠΈΡΠΎΠ²Π°Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ (*D) &= ~S);
set β ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ Π±ΠΈΡΡ Π² Π·Π½Π°ΡΠ΅Π½ΠΈΠΈ ΠΎΠΏΠ΅ΡΠ°Π½Π΄Π° (Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ ΠΏΠΎΠ±ΠΈΡΠΎΠ²Π°Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ (*D) |= S);
toggle β ΠΈΠ½Π²Π΅ΡΡΠΈΡΠΎΠ²Π°ΡΡ Π±ΠΈΡΡ Π² Π·Π½Π°ΡΠ΅Π½ΠΈΠΈ ΠΎΠΏΠ΅ΡΠ°Π½Π΄Π° (Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ ΠΏΠΎΠ±ΠΈΡΠΎΠ²Π°Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ (*D) ^= S);
D β ΠΈΠΌΠ΅Π½Π½ΠΎ ΡΠΎΡ ΠΎΠ±ΡΠ΅ΠΊΡ, Π½Π°Π΄ ΠΊΠΎΡΠΎΡΡΠΌ ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΠ΅ΡΡΡ Π°ΡΠΎΠΌΠ°ΡΠ½Π°Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ;
S β Π²ΡΠΎΡΠΎΠΉ ΠΎΠΏΠ΅ΡΠ°Π½Π΄ ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΠ΅ΠΌΠΎΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ.
ΠΠ²Π΅ ΡΠΎΡΠΌΡ Π°ΡΠΎΠΌΠ°ΡΠ½ΡΡ ΡΡΠ½ΠΊΡΠΈΠΉ Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ ΠΎΡΠ»ΠΈΡΠ°ΡΡΡΡ ΡΠ΅ΠΌ, ΡΡΠΎ ΠΏΠ΅ΡΠ²Π°Ρ ΠΈΠ· Π½ΠΈΡ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ Π±Π΅Π· Π²ΠΎΠ·Π²ΡΠ°ΡΠ° Π·Π½Π°ΡΠ΅Π½ΠΈΡ, Π° Π²ΡΠΎΡΠ°Ρ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΎΠΏΠ΅ΡΠ°Π½Π΄ D ΠΈΠΌΠ΅Π» Π΄ΠΎ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ (Ρ.e. ΠΏΡΠ΅ΠΆΠ½Π΅Π΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅, ΠΊΠ°ΠΊ ΡΡΠΎ Π΄Π΅Π»Π°ΡΡ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΏΡΠ΅ΡΠΈΠΊΡΠ½ΡΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ ΠΈΠ½ΠΊΡΠ΅ΠΌΠ΅Π½ΡΠ° ++D ΠΈ Π΄Π΅ΠΊΡΠ΅ΠΌΠ΅Π½ΡΠ° --D, Π² ΠΎΡΠ»ΠΈΡΠΈΠ΅ ΠΎΡ ΠΏΠΎΡΡΡΠΈΠΊΡΠ½ΡΡ D++ ΠΈ D--).
ΠΠ°ΡΠ΅ΠΌ Π½ΡΠΆΠ½Ρ Π΄Π²Π΅ ΡΠΎΡΠΌΡ Π΄Π»Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ? Π’Π΅Ρ Π½ΠΈΡΠ΅ΡΠΊΠ°Ρ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡ QNX ΡΡΠ²Π΅ΡΠΆΠ΄Π°Π΅Ρ, ΡΡΠΎ Π²ΡΠΎΡΠ°Ρ ΡΠΎΡΠΌΠ° ΠΌΠΎΠΆΠ΅Ρ Π²ΡΠΏΠΎΠ»Π½ΡΡΡΡΡ Π΄ΠΎΠ»ΡΡΠ΅. Π‘ΠΏΡΠ°Π²Π΅Π΄Π»ΠΈΠ²ΠΎΡΡΡ ΡΡΠΎΠ³ΠΎ ΡΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΡ ΠΈ Π½Π°ΡΠΊΠΎΠ»ΡΠΊΠΎ Π΄ΠΎΠ»ΡΡΠ΅ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ Π²ΡΠΎΡΠ°Ρ ΡΠΎΡΠΌΠ°, ΠΌΡ ΡΠΊΠΎΡΠΎ ΡΠ²ΠΈΠ΄ΠΈΠΌ Π½Π° ΠΏΡΠΈΠΌΠ΅ΡΠ°Ρ .
ΠΡΠ°ΠΊ, Ρ Π½Π°Ρ Π΅ΡΡΡ 10 ΡΡΠ½ΠΊΡΠΈΠΉ Π΄Π»Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΏΡΡΠΈ Π°ΡΠΎΠΌΠ°ΡΠ½ΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ:
atomic_add() atomic_add_value()
atomic_sub() atomic_sub_value()
atomic_clr() atomic_clr_value()
atomic_set() atomic_set_value()
atomic_toggle() atomic_toggle_value()
ΠΠ°ΠΊ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ Π°ΡΠΎΠΌΠ°ΡΠ½ΡΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ? ΠΠ±ΡΡΠ½ΠΎ Π΄Π»Ρ ΠΏΡΠ΅Π΄ΠΎΡΠ²ΡΠ°ΡΠ΅Π½ΠΈΡ ΠΎΠ΄Π½ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ Π½Π΅ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ ΡΡΠ΅ΡΡΠΈΠΊΠ° ΠΈΠ½Π΄Π΅ΠΊΡΠ° ΠΌΡ Π²ΡΠ½ΡΠΆΠ΄Π΅Π½Ρ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΡΡ ΡΠ΅ΠΊΡΠΈΡ, ΠΎΠ±ΠΎΠ·Π½Π°ΡΠ°Ρ Π΅Π΅, ΡΠΊΠ°ΠΆΠ΅ΠΌ, ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡΠΌΠΈ Π½Π°Π΄ ΠΌΡΡΡΠ΅ΠΊΡΠΎΠΌ. Π ΡΠ°ΡΡΠ½ΠΎΡΡΠΈ, Π² ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠ΅ Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΠ· ΡΠ°Π·Π»ΠΈΡΠ½ΡΡ ΠΏΠΎΡΠΎΠΊΠΎΠ² ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎ Π΄ΠΎΠΏΠΈΡΡΠ²Π°ΡΡ Π½Π΅ΠΊΠΎΡΠΎΡΡΠ΅ Π±Π°ΠΉΡΠΎΠ²ΡΠ΅ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ Π² Π΅Π΄ΠΈΠ½ΡΠΉ Π±ΡΡΠ΅Ρ:
// Π³Π»ΠΎΠ±Π°Π»ΡΠ½ΡΠ΅ ΠΎΠΏΠΈΡΠ°Π½ΠΈΡ, Π΄ΠΎΡΡΡΠΏΠ½ΡΠ΅ Π²ΡΠ΅ΠΌ ΠΏΠΎΡΠΎΠΊΠ°ΠΌ
const unsigned int N = ...
uint8_t buf[N];
// ΠΈΠ½Π΄Π΅ΠΊΡ ΡΠ΅ΠΊΡΡΠ΅ΠΉ ΠΏΠΎΠ·ΠΈΡΠΈΠΈ Π·Π°ΠΏΠΈΡΠΈ
unsigned int ind = 0;
// ΠΎΠ±ΡΠΈΠΉ ΠΌΡΡΡΠ΅ΠΊΡ, Π΄ΠΎΡΡΡΠΏΠ½ΡΠΉ ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡ ΠΈΠ· ΠΏΠΎΡΠΎΠΊΠΎΠ²
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
...
// Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΈΠ· ΠΏΠΎΡΠΎΠΊΠΎΠ²:
uint8_t res[M]; // ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ Π½Π΅ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ
unsigned int how = ... // ΡΠ΅Π°Π»ΡΠ½Π°Ρ Π΄Π»ΠΈΠ½Π° ΡΡΠΎΠ³ΠΎ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ°
pthread_mutex_lock(&mutex);
memcpy((void*)buf + ind, (void*)res, how);
ind += how;
pthread_mutex_unlock(&mutex);
ΠΡΠΏΠΎΠ»ΡΠ·ΡΡ Π°ΡΠΎΠΌΠ°ΡΠ½ΡΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡΠΎΡ ΠΏΡΠΎΡΠ΅ΡΡ Π·Π°ΠΏΠΈΡΠ°ΡΡ ΡΠ°ΠΊ (Π²ΡΠ΅ Π³Π»ΠΎΠ±Π°Π»ΡΠ½ΡΠ΅ ΠΎΠΏΠΈΡΠ°Π½ΠΈΡ ΠΎΡΡΠ°ΡΡΡΡ Π½Π΅ΠΈΠ·ΠΌΠ΅Π½Π½ΡΠΌΠΈ):
// Π³Π»ΠΎΠ±Π°Π»ΡΠ½ΡΠ΅ ΠΎΠΏΠΈΡΠ°Π½ΠΈΡ, Π΄ΠΎΡΡΡΠΏΠ½ΡΠ΅ Π²ΡΠ΅ΠΌ ΠΏΠΎΡΠΎΠΊΠ°ΠΌ
...
// ΠΈΠ½Π΄Π΅ΠΊΡ ΡΠ΅ΠΊΡΡΠ΅ΠΉ ΠΏΠΎΠ·ΠΈΡΠΈΠΈ Π·Π°ΠΏΠΈΡΠΈ
volatile unsigned int ind = 0;
...
// Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΈΠ· ΠΏΠΎΡΠΎΠΊΠΎΠ²:
uint8_t res[M]; // ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ Π½Π΅ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ
unsigned int how = ... // ΡΠ΅Π°Π»ΡΠ½Π°Ρ Π΄Π»ΠΈΠ½Π° ΡΡΠΎΠ³ΠΎ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ°
memcpy((void*)buf + atomic_add_value(ind, how), (void*)res, how);
ΠΠ»ΠΈ Π΄Π°ΠΆΠ΅ ΡΠ°ΠΊ:
// Π³Π»ΠΎΠ±Π°Π»ΡΠ½ΡΠ΅ ΠΎΠΏΠΈΡΠ°Π½ΠΈΡ, Π΄ΠΎΡΡΡΠΏΠ½ΡΠ΅ Π²ΡΠ΅ΠΌ ΠΏΠΎΡΠΎΠΊΠ°ΠΌ
...
// ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ ΡΠ΅ΠΊΡΡΠ΅ΠΉ ΠΏΠΎΠ·ΠΈΡΠΈΠΈ Π·Π°ΠΏΠΈΡΠΈ:
volatile unsigned int ind = (unsigned int)buf;
...
// Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΈΠ· ΠΏΠΎΡΠΎΠΊΠΎΠ²:
memcpy((void*)atomic_add_value(ind, how), (void*)res, how);
Π ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅ΠΌ ΡΠ»ΡΡΠ°Π΅ ΡΡΠΎ, ΠΊΠΎΠ½Π΅ΡΠ½ΠΎ, ΡΡΡΠΊΠ°ΡΠ΅ΡΡΠ²ΠΎ, ΠΏΠΎΡΡΡΠΎΠ΅Π½Π½ΠΎΠ΅ Π½Π° ΡΠΎΠΌ, ΡΡΠΎ Π² 32-ΡΠ°Π·ΡΡΠ΄Π½ΠΎΠΉ Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ΅ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ΠΈΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ ΠΈ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ unsigned int ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡΡ, Π½ΠΎ ΡΡΠΎ Β«ΡΠ°Π±ΠΎΡΠ°ΡΡΠ΅Π΅ ΡΡΡΠΊΠ°ΡΠ΅ΡΡΠ²ΠΎΒ» ΠΈ ΡΠ°Π±ΠΎΡΠ°ΡΡΠ΅Π΅ ΠΈΠ½ΠΎΠ³Π΄Π° Π²Π΅ΡΡΠΌΠ° ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎ.
Π’Π΅Ρ Π½ΠΈΠΊΠ° ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΡ Π°ΡΠΎΠΌΠ°ΡΠ½ΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ ΠΎΠΊΠ°Π·ΡΠ²Π°Π΅ΡΡΡ ΠΊΡΠ°ΠΉΠ½Π΅ ΡΠ΄ΠΎΠ±Π½ΠΎΠΉ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΏΡΠΈ ΠΎΡΡΡΠ΅ΡΡΠ²Π»Π΅Π½ΠΈΠΈ Π²ΡΠ²ΠΎΠ΄Π°, ΡΠ°ΡΡΠΎ Π΄ΠΈΠ°Π³Π½ΠΎΡΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ, ΠΈΠ· ΡΠ°Π·Π»ΠΈΡΠ½ΡΡ ΠΏΠΎΡΠΎΠΊΠΎΠ². ΠΠΎΠ»ΠΎΠΆΠΈΠΌ, Π½Π°ΠΌ Π½ΡΠΆΠ½ΠΎ Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΈΠ· ΠΌΠ½ΠΎΠ³ΠΈΡ ΠΏΠΎΡΠΎΠΊΠΎΠ² Π²ΡΠ²ΠΎΠ΄ΠΈΡΡ Π΄ΠΈΠ°Π³Π½ΠΎΡΡΠΈΡΠ΅ΡΠΊΡΡ ΡΡΡΠΎΠΊΡ ΠΏΡΠΈ Π΄ΠΎΡΡΠΈΠΆΠ΅Π½ΠΈΠΈ ΠΈΠΌΠΈ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΉ ΡΠΎΡΠΊΠΈ ΠΈΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ:
cout << "ΠΡΠΎ Π²ΡΠ²ΠΎΠ΄ ΠΏΠΎΡΠΎΠΊΠ° " << pthread_self() << endl;
ΠΠΎ ΡΠ°ΠΊ Π΄Π΅Π»Π°ΡΡ Π½Π΅Π»ΡΠ·Ρ: ΠΏΡΠΈ ΡΠ°ΠΊΠΎΠΌ ΡΠ΅ΡΠ΅Π½ΠΈΠΈ Ρ Π½Π°Ρ ΠΏΠΎΡΠ²Π»ΡΡΡΡΡ 2 ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ, ΠΎΠ΄Π½Π° ΠΈΠ· ΠΊΠΎΡΠΎΡΡΡ ΠΎΡΠ΅Π²ΠΈΠ΄Π½Π°, Π° Π΄ΡΡΠ³Π°Ρ β Π½Π΅ ΠΎΡΠ΅Π½Ρ:
1. ΠΡΠ²ΠΎΠ΄Ρ ΡΠ°Π·Π½ΡΡ ΠΏΠΎΡΠΎΠΊΠΎΠ² ΠΌΠΎΠ³ΡΡ Β«ΡΠΌΠ΅ΡΠΈΠ²Π°ΡΡΡΡΒ»; Π±ΠΎΠ»Π΅Π΅ ΡΠΎΠ³ΠΎ, Π·Π° ΡΡΠ΅Ρ Π±ΡΡΠ΅ΡΠΈΠ·Π°ΡΠΈΠΈ Π²ΡΠ²ΠΎΠ΄Π° Π½Π΅ΠΊΠΎΡΠΎΡΡΠ΅ Β«ΡΠ²Π°Π½ΡΠ΅Β» ΡΡΠ°Π³ΠΌΠ΅Π½ΡΡ ΠΌΡ Π±ΡΠ΄Π΅ΠΌ Π½Π°Π±Π»ΡΠ΄Π°ΡΡ Π΄Π²Π°ΠΆΠ΄Ρ. ΠΠ΄Π½ΠΈΠΌ ΡΠ»ΠΎΠ²ΠΎΠΌ, Π½Π°Ρ Π²ΡΠ²ΠΎΠ΄ ΠΎΠΊΠ°ΠΆΠ΅ΡΡΡ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ Β«Π½Π΅ΡΠΈΡΠ°Π±Π΅Π»ΡΠ½ΡΠΌΒ».
2. ΠΡΠΈ ΠΎΡΡΡΠ΅ΡΡΠ²Π»Π΅Π½ΠΈΠΈ Π²ΡΠ²ΠΎΠ΄Π° Π² ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ΅ ΠΏΠΎΡΠΎΠΊΠ° ΠΏΠΎΡΡΠΈ Π½Π°Π²Π΅ΡΠ½ΡΠΊΠ° Π² ΠΏΡΠΎΡΠ΅ΡΡΠ΅ Π²ΡΠ²ΠΎΠ΄Π° Π±ΡΠ΄ΡΡ Π²ΡΠΏΠΎΠ»Π½ΡΡΡΡΡ ΡΠΈΡΡΠ΅ΠΌΠ½ΡΠ΅ Π²ΡΠ·ΠΎΠ²Ρ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΏΠΎΡΡΠ΅Π±ΡΡΡ Π½ΠΎΠ²ΠΎΠΉ Π΄ΠΈΡΠΏΠ΅ΡΡΠ΅ΡΠΈΠ·Π°ΡΠΈΠΈ ΠΈ ΠΏΡΠΈΠ²Π΅Π΄ΡΡ ΠΊ Π²ΡΡΠ΅ΡΠ½Π΅Π½ΠΈΡ ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ°. ΠΡΠΈ ΡΡΠΎΠΌ ΠΏΠΎΡΡΠ΄ΠΎΠΊ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΈ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ ΠΎΡ ΠΏΠΎΡΠΎΠΊΠ° ΠΊ ΠΏΠΎΡΠΎΠΊΡ ΠΏΡΠΈ Π½Π°Π»ΠΈΡΠΈΠΈ ΠΎΡΠ»Π°Π΄ΠΎΡΠ½ΠΎΠ³ΠΎ Π²ΡΠ²ΠΎΠ΄Π° Π±ΡΠ΄Π΅Ρ ΠΎΡΠ»ΠΈΡΠ°ΡΡΡΡ ΠΎΡ ΠΏΠΎΡΡΠ΄ΠΊΠ° ΠΏΡΠΈ Π΅Π³ΠΎ ΠΎΡΡΡΡΡΡΠ²ΠΈΠΈ. Π ΡΡΠΎ, Π½Π°Π²Π΅ΡΠ½ΠΎΠ΅, Π½Π΅ ΡΠΎΠ²ΡΠ΅ΠΌ ΡΠΎ, ΡΡΠΎ ΠΌΡ ΠΎΠΆΠΈΠ΄Π°Π»ΠΈ. Π ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ΅ ΠΏΡΠΈ Π½Π°Π»ΠΈΡΠΈΠΈ ΠΎΡΠ»Π°Π΄ΠΎΡΠ½ΠΎΠ³ΠΎ Π²ΡΠ²ΠΎΠ΄Π° ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π½Π°Π±Π»ΡΠ΄Π°ΡΡ ΡΠΎΠ²ΡΠ΅ΠΌ Π½Π΅ ΡΡ ΠΊΠ°ΡΡΠΈΠ½Ρ, Π΄Π»Ρ ΠΈΠ·ΡΡΠ΅Π½ΠΈΡ ΠΊΠΎΡΠΎΡΠΎΠΉ ΡΡΠΎΡ Π²ΡΠ²ΠΎΠ΄, ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΠΎ, ΠΈ ΠΏΡΠ΅Π΄Π½Π°Π·Π½Π°ΡΠ΅Π½.
ΠΡΠΈ ΡΡΡΠ΅ΠΊΡΡ Π½Π΅ ΡΠ²ΡΠ·Π°Π½Ρ Ρ ΠΊΠ°ΠΊΠΎΠΉ-ΡΠΎ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎΠΉ ΡΠΎΡΠΌΠΎΠΉ Π²ΡΠ²ΠΎΠ΄Π°, ΡΠ°ΠΊΠΎΠΉ ΠΊΠ°ΠΊ Π²ΡΠ²ΠΎΠ΄ Π² ΠΏΠΎΡΠΎΠΊ, ΠΏΠΎΠΊΠ°Π·Π°Π½Π½ΡΠΉ Π²ΡΡΠ΅; ΡΠΎΡΠ½ΠΎ ΡΠ°ΠΊ ΠΆΠ΅ Π±ΡΠ΄Π΅Ρ Π²Π΅ΡΡΠΈ ΡΠ΅Π±Ρ ΠΈ ΡΡΠ°Π΄ΠΈΡΠΈΠΎΠ½Π½ΡΠΉ Π²ΡΠ·ΠΎΠ² printf(...).
ΠΡΠΎΠ±Π»Π΅ΠΌΠ° ΠΎΡΠ΅Π½Ρ ΠΏΡΠΎΡΡΠΎ ΡΠ΅ΡΠ°Π΅ΡΡΡ, Π΅ΡΠ»ΠΈ Π²ΠΌΠ΅ΡΡΠΎ Π½Π΅ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²Π΅Π½Π½ΠΎΠ³ΠΎ Π²ΡΠ²ΠΎΠ΄Π° ΠΈΠ· ΠΏΠΎΡΠΎΠΊΠΎΠ² ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎ ΡΠ±ΡΠ°ΡΡΠ²Π°ΡΡ Π²ΡΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ Π² ΠΏΡΠΎΠΌΠ΅ΠΆΡΡΠΎΡΠ½ΡΠΉ Π±ΡΡΠ΅Ρ, ΠΊΠΎΡΠΎΡΡΠΉ Π±ΡΠ΄Π΅Ρ Π²ΡΠ²ΠΎΠ΄ΠΈΡΡΡΡ Π² ΡΠ΅ ΠΏΠ΅ΡΠΈΠΎΠ΄Ρ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ, ΠΊΠΎΠ³Π΄Π° Π·Π°ΠΏΠΈΡΡ Π² Π½Π΅Π³ΠΎ Π½Π΅ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΡΡ:
const int N = ... , M = ...;
char buf[N];
volatile unsigned ind = 0;
...
// Π° Π²ΠΎΡ ΡΡΠΎ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΡΡ ΠΈΠ· ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ°
char tbuf[M];
sprintf(tbuf, "ΠΡΠΎ Π²ΡΠ²ΠΎΠ΄ ΠΏΠΎΡΠΎΠΊΠ° %X", pthread_self());
strcpy(buf + atomic_add_value(ind, strlen(tbuf)), tbuf);
Π Π½Π°ΠΊΠΎΠ½Π΅Ρ, ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅Π΅: Π΅ΡΡΡ Π»ΠΈ ΡΠΌΡΡΠ» Π²ΠΎ Π²Π²Π΅Π΄Π΅Π½ΠΈΠΈ ΡΡΠΎΠ³ΠΎ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΠΎΠ³ΠΎ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌΠ°, Π΅ΡΠ»ΠΈ Π²ΡΠ΅Π³Π΄Π° ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ Π°Π»ΡΡΠ΅ΡΠ½Π°ΡΠΈΠ²Π½Π°Ρ ΡΠΎΡΠΌΠ° ΠΎΡΠ³Π°Π½ΠΈΠ·Π°ΡΠΈΠΈ ΡΠ°ΠΊΠΎΠΉ ΠΆΠ΅ Π·Π°ΡΠΈΡΡ Π΄ΠΎΡΡΡΠΏΠ° ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²ΠΎΠΌ ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΠΎΠΉ ΡΠ΅ΠΊΡΠΈΠΈ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΏΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ ΠΌΡΡΡΠ΅ΠΊΡΠ°)? Π‘ΡΠ°Π²Π½ΠΈΠΌ (ΡΠ°ΠΉΠ» a1.cc) Π²ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ Π·Π°ΡΡΠ°ΡΡ ΠΏΡΠΈ ΠΌΠ½ΠΎΠ³ΠΎΠΊΡΠ°ΡΠ½ΠΎΠΌ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π΄Π»Ρ ΡΠ»ΡΡΠ°Π΅Π² Π°ΡΠΎΠΌΠ°ΡΠ½ΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ ΠΈ ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΠΎΠΉ ΡΠ΅ΠΊΡΠΈΠΈ Π½Π° Π±Π°Π·Π΅ ΠΌΡΡΡΠ΅ΠΊΡΠ° (ΠΌΡ Π±Π΅ΡΠ΅ΠΌ ΠΈΠΌΠ΅Π½Π½ΠΎ ΠΌΡΡΡΠ΅ΠΊΡ, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ ΠΈΠ· Π²ΡΠ΅Ρ ΠΏΡΠΈΠΌΠΈΡΠΈΠ²ΠΎΠ² ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠΈ ΠΎΠ½ ΡΠ°ΠΌΡΠΉ Π½ΠΈΠ·ΠΊΠΎΡΡΠΎΠ²Π½Π΅Π²ΡΠΉ ΠΈ Π±ΡΡΡΡΡΠΉ):
Π‘ΡΠ°Π²Π½Π΅Π½ΠΈΠ΅ ΠΌΡΡΡΠ΅ΠΊΡΠ° ΠΈ Π΄Π²ΡΡ ΡΠΎΡΠΌ Π²ΡΠ·ΠΎΠ²Π° Π°ΡΠΎΠΌΠ°ΡΠ½ΠΎΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ#include <stdlib.h>
#include <stdio.h>
#include <iostream.h>
#include <unistd.h>
#include <inttypes.h>
#include <pthread.h>
#include <sys/neutrino.h>
#include <atomic.h>
int main(int argc, char *argv[]) {
uint64_t N = 100000;
bool atom = false, value = false;
int opt, val;
while ((opt = getopt(argc, argv, "n:av")) != -1) {
switch(opt) {
case 'n': // ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΏΠΎΠ²ΡΠΎΡΠ΅Π½ΠΈΠΉ
if (sscanf(optarg, "%i", &val) != 1)
cout << "parse command line error" << endl, exit(EXIT_FAILURE);
if (val > 0) N = val;
break;
// ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π°ΡΠΎΠΌΠ°ΡΠ½ΡΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ
case 'a':
atom = true;
break;
// ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠΎΡΠΌΡ, Π²ΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅
case 'v':
value = true;
break;
default:
exit(EXIT_FAILURE);
}
}
// Π·Π°ΠΌΠ΅ΡΡΠ΅ΡΡΡ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠ½ΡΡ ΡΠΈΠΊΠ»ΠΎΠ² Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΡΠ»ΡΡΠ°Ρ
uint64_t i = N, t = ClockCycles();
volatile unsigned ind = 0;
if (!atom) {
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
while (i--) {
pthread_mutex_lock(&mutex);
ind++;
pthread_mutex_unlock(&mutex);
}
} else if (value)
while (i--) atomic_add_value(&ind, 1);
else while (i--) atomic_add(&ind, 1);
t = ClockCycles() - t;
cout << "all cycles - " << t << "; on operation - "
<< t / N << endl;
exit(EXIT_SUCCESS);
}
ΠΠΎΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ ΠΏΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΠΎΠΉ ΡΠ΅ΠΊΡΠΈΠΈ:
# nice -n-19 a1 -n10000000
all cycles - 1120872156; on operation - 112
Π Π΅Π·ΡΠ»ΡΡΠ°Ρ Ρ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ Π°ΡΠΎΠΌΠ°ΡΠ½ΠΎΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ, Π½Π΅ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡΠ΅ΠΉ Π·Π½Π°ΡΠ΅Π½ΠΈΡ:
# nice -n-19 a1 -n10000000 -a
all cycles β 391018203; on operation - 39
Π Π΅Π·ΡΠ»ΡΡΠ°Ρ Ρ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ Π°ΡΠΎΠΌΠ°ΡΠ½ΠΎΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ, Π²ΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡΠ΅ΠΉ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ (ΠΎΠ±Π΅ΡΠ°Π½Π½Π°Ρ ΡΠ°Π·Π½ΠΈΡΠ° ΡΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ ΠΏΠΎΡΡΠ΄ΠΊΠ° 10%):
# nice -n-19 a1 -n10000000 -a -v