Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«QNX/UNIX: Анатомия ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΠΈΠ·ΠΌΠ°Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 44

Автор ОлСг Π¦ΠΈΠ»ΡŽΡ€ΠΈΠΊ

Помимо Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½Ρ‹Ρ… ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ Π½Π°Π΄ этой ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΌΠΎΠ³ΡƒΡ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ Π»ΡŽΠ±Ρ‹Π΅ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ дСйствия, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ бСзопасными Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠΉ срСдС: инициализация, присваиваниС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ, сравнСния. Π‘ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ³ΠΎ, ΠΏΡ€ΠΈ Π²Ρ‹Ρ…ΠΎΠ΄Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π·Π° ΠΎΠ±Π»Π°ΡΡ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠ³ΠΎ ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠ³ΠΎ доступа ΠΊ этой ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΎΠ½Π° ΠΌΠΎΠΆΠ΅Ρ‚ Π΄Π°Π»Π΅Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π»ΡŽΠ±Ρ‹ΠΌ Ρ‚Ρ€Π°Π΄ΠΈΡ†ΠΈΠΎΠ½Π½Ρ‹ΠΌ ΠΈ ΠΏΡ€ΠΈΠ²Ρ‹Ρ‡Π½Ρ‹ΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ.

Π’Π°ΠΆΠ½ΠΎ Ρ‚Π°ΠΊΠΆΠ΅ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ Ρ‚Π΅Ρ€ΠΌΠΈΠ½ Β«Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½ΠΎΡΡ‚ΡŒΒ» относится Π½Π΅ ΠΊ особым свойствам Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π΄Π°Π½Π½Ρ‹Ρ…, Π° ΠΊ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Π½ΠΎΠΌΡƒ ряду ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠΆΠ½ΠΎ бСзопасно Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ Π½Π°Π΄ этим ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠΉ срСдС.

ΠžΠ±Ρ‰ΠΈΠΉ Π²ΠΈΠ΄ ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏΠΎΠ² ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΈΠ· Π΄Π²ΡƒΡ… Π³Ρ€ΡƒΠΏΠΏ Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½Ρ‹Ρ… ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ:

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