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

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

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

РассматриваСмыС ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Ρ‹ слуТат ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠΈΠ°Π»ΡŒΠ½ΠΎ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌ цСлям. ΠœΡŒΡŽΡ‚Π΅ΠΊΡ, ΠΊΠ°ΠΊ ΡƒΠΆΠ΅ Π±Ρ‹Π»ΠΎ сказано Ρ€Π°Π½Π΅Π΅, ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ Π² ΠΏΠ΅Ρ€Π²ΡƒΡŽ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ для Ρ€Π΅Π³Π»Π°ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ доступа ΠΊ участкам ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°. Π‘Π΅ΠΌΠ°Ρ„ΠΎΡ€Ρ‹ ΠΆΠ΅ большС ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Ρ‹ для Ρ€Π΅Π³Π»Π°ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ порядка доступа ΠΊ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌ Π΄Π°Π½Π½Ρ‹Ρ…. ΠšΠ»Π°ΡΡΠΈΡ‡Π΅ΡΠΊΠΈΠΌΠΈ Π·Π°Π΄Π°Ρ‡Π°ΠΌΠΈ этого класса ΡΠ²Π»ΡΡŽΡ‚ΡΡ Π·Π°Π΄Π°Ρ‡ΠΈ Β«ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ-ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒΒ», ΠΊΠΎΠ³Π΄Π° M ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ ΡΠΎΠ·Π΄Π°ΡŽΡ‚ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… (читая эти Π΄Π°Π½Π½Ρ‹Π΅ с Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹Ρ… Π²Π½Π΅ΡˆΠ½ΠΈΡ… устройств, ΠΈΠ»ΠΈ создавая ΠΈΡ… ΠΊΠ°ΠΊ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΡ… вычислСний, ΠΈΠ»ΠΈ Π»ΡŽΠ±Ρ‹ΠΌ Π΄Ρ€ΡƒΠ³ΠΈΠΌ способом), Π° N ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΉ нСзависимо Π±Π΅Ρ€ΡƒΡ‚ ΠΏΡ€ΠΎΠΈΠ·Π²Π΅Π΄Π΅Π½Π½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… Π½Π° ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ.

Π­Ρ‚ΠΎ Π½Π°ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ±Ρ‰ΠΈΠΉ ΠΈ часто Π²ΡΡ‚Ρ€Π΅Ρ‡Π°ΡŽΡ‰ΠΈΠΉΡΡ класс Π·Π°Π΄Π°Ρ‡, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ для Π½Π΅Π³ΠΎ ΠΏΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠΈΠΉ «скСлСт» Π² Π²ΠΈΠ΄Π΅ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ прилоТСния, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ отслСТиваниС порядка доступа ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²Π»ΡΡ‚ΡŒ счСтный сСмафор (Ρ„Π°ΠΉΠ» sy22.cc). Для простоты понимания ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ сдСлано ΠΊΠ°ΠΊ трансформация ΠΊΠΎΠ΄Π° ΠΏΡ€Π΅Π΄ΡˆΠ΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΉ Π³Ρ€ΡƒΠΏΠΏΡ‹ тСстов. Π’ качСствС ΠΈΠΌΠΈΡ‚Π°Ρ†ΠΈΠΈ производства ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠ°ΠΊ ΠΈ Π² качСствС Π΅Π³ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΌ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ пассивная ΠΏΠ°ΡƒΠ·Π° (delay()) Π½Π° ΡΠ»ΡƒΡ‡Π°ΠΉΠ½ΡƒΡŽ Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρƒ (производство ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π΄Π°Π½Π½Ρ‹Ρ… Π² ΠΊΠΎΠ΄Π΅ Π½Π΅ ΠΏΠΎΠΊΠ°Π·Π°Π½Ρ‹, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ это Π½Π΅ относится ΠΊ сущСству рассматриваСмого β€” нас ΠΈΠ½Ρ‚Π΅Ρ€Π΅ΡΡƒΡŽΡ‚ процСссы синхронизации этих ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ, Π° Π½Π΅ сами ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ).

ΠšΡ€ΠΎΠΌΠ΅ основной нашСй Ρ†Π΅Π»ΠΈ это ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ дСмонстрируСт:

β€’ ΠŸΡ€Π°ΠΊΡ‚ичСскоС использованиС ΠΏΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ (ΠΎΡ‚ΠΌΠ΅Π½Ρ‹) ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Β«ΠΈΠ·Π²Π½Π΅Β» с ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ состояниСм Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅ΠΌΠΎΡΡ‚ΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΈ расстановкой Ρ‚ΠΎΡ‡Π΅ΠΊ ΠΎΡ‚ΠΌΠ΅Π½Ρ‹, ΠΎ Ρ‡Π΅ΠΌ ΠΌΡ‹ ΡƒΠΆΠ΅ Π³ΠΎΠ²ΠΎΡ€ΠΈΠ»ΠΈ Ρ€Π°Π½Π΅Π΅.

β€’ Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½Ρ‹Ρ… (Π½Π΅ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°Π΅ΠΌΡ‹Ρ…) ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, atomic_add_value()), ΠΎ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ΡŒ Ρ‡ΡƒΡ‚ΡŒ ΠΏΠΎΠ·ΠΆΠ΅.

β€’ Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Ρ€Π΅Π΅Π½Ρ‚Π΅Ρ€Π°Π±Π΅Π»ΡŒΠ½Ρ‹Ρ… Ρ„ΠΎΡ€ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ, бСзопасных Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠΉ срСдС (rand_r() вмСсто rand()).

Один ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ β€” T ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΉ

#include <stdlib.h>

#include <stdio.h>

#include <iostream.h>

#include <unistd.h>

#include <pthread.h>

#include <errno.h>

#include <semaphore.h>

#include <atomic.h>


const int D = 10;

unsigned int T = 2;

static sem_t sem;

pthread_t* tid;


void* writer(void* data) {

 unsigned long i = (int)(data); // ΠΎΠ±Ρ‰ΠΈΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€ Π²Ρ‹Π±ΠΎΡ€ΠΊΠΈ

 unsigned int s = 1;

 while (i-- > 0) {

  delay((long)rand_r(&s) * D / RAND_MAX + 1);

  sem_post(&sem); // ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΡ€ΠΎΠΈΠ·Π²Π΅Π΄Π΅Π½

 }

 for (i = 0; i < T; i++) pthread_cancel(tid[i + 1]);

 return NULL;

}


static char *str; // строка Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅ΠΉ диагностики

static volatile unsigned ind = 0;


void* reader(void*) {

 char tid[8];

 sprintf(tid, "%X", pthread_self());

 unsigned int s = rand();

 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);

 while(true) {

  sem_wait(&sem); // ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π΄Π°Π½Π½Ρ‹Ρ…

  str[atomic_add_value(&ind, 1)] = *tid;

  pthread_testcancel();

  delay((long)rand_r(&s) * D * T / RAND_MAX + 1);

 }

 return NULL;

}


int main(int argc, char *argv[]) {

 unsigned long N = 1000;

 int opt, val;

 while ((opt = getopt(argc, argv, "n:t:")) != -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 't':

   if (sscanf(optarg, "%i", &val) != 1)

    cout << "parse command line error" << endl, exit(EXIT_FAILURE);

   if (val > 0) T = val;

   break;

  default:

   exit(EXIT_FAILURE);

  }

 }

 str = new char[N + 1];

 tid = new pthread_t[T + 1];

 if (sem_init(&sem, 0, 0))

  perror("semaphore init"), exit(EXIT_FAILURE);

 if (pthread_create(tid, NULL, writer, (void*)N) >= EOK)

  perror("writer create error"), exit(EXIT_FAILURE);

 for (int i = 0; i < T; i++)

  if (pthread_create(tid + i + 1, NULL, reader, NULL) != EOK)

   perror("reader create error"), exit(EXIT_FAILURE);

 for (int i = 0; i < T; i++)

  pthread_join(tid[i], NULL);

 sem_destroy(&sem);

 delete [] tid;

 str[ind] = '\0';

 cout << str << endl;

 delete [] str;

 exit(EXIT_SUCCESS);

}

Π’ΠΎΡ‚ ΠΊΠ°ΠΊ выглядит Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния этой ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ (Π²ΠΎ ΠΈΠ·Π±Π΅ΠΆΠ°Π½ΠΈΠ΅ внСсСния Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ синхронизма Π² качСствС ΠΎΠ±Ρ‰Π΅Π³ΠΎ числа Ρ†ΠΈΠΊΠ»ΠΎΠ² «производства» ΠΈ числа ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΉ Π²Ρ‹Π±Ρ€Π°Π½Ρ‹ Π²Π·Π°ΠΈΠΌΠ½ΠΎ простыС числа):

# sy22 -n200 -t13

3456789ABCDEF7936A8547E39DCB45F67A59B84D37EC64F395B6AEF78B9DF34CB53B86A5FEDF975B3A8EC46FB8AD954736FA78C3ED46F7B594EC7B83AC6F9D4BCE569A73F86BCAD74C536EB79F5C8DA5B463EFBC7D937AEC85FDE4566CAF69DE7F385CA6

Π₯ΠΎΡ€ΠΎΡˆΠΎ Π²ΠΈΠ΄Π½ΠΎ, ΠΊΠ°ΠΊ строго ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠΎΠ½Π°Ρ‡Π°Π»Ρƒ порядок доступа ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΉ ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌ Π΄Π°Π½Π½Ρ‹Ρ… дСсинхронизируСтся ΠΈ становится хаотичСским: ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ освободившийся ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ приступаСт ΠΊ Ρ€Π°Π±ΠΎΡ‚Π΅ Π½Π°Π΄ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠ°ΠΊ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚ΠΎΡ‚ становится доступСн.

АтомарныС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ

АтомарныС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π½Π΅ относятся ΠΊ элСмСнтам синхронизации ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Ρ‹Ρ… Π²Π΅Ρ‚Π²Π΅ΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. Но ΠΈΠΌ слСдуСт ΡƒΠ΄Π΅Π»ΠΈΡ‚ΡŒ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ ΠΏΠΎ Π΄Π²ΡƒΠΌ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π°ΠΌ. Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ β€” это простоС ΠΈ эффСктивноС срСдство, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰Π΅Π΅ Π²ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΡ… случаях ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ использования ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠΎΠ² синхронизации. А Π²ΠΎ-Π²Ρ‚ΠΎΡ€Ρ‹Ρ…, Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π·Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ Π²Ρ‹ΠΏΠ°Π΄Π°ΡŽΡ‚ ΠΈΠ· рассмотрСния ΠΈΠ·-Π·Π° ΠΈΡ… двойствСнного полоТСния: ΠΏΡ€ΠΈ обсуТдСнии ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΠΈΠ·ΠΌΠ° ΠΈ синхронизации ΠΎΠ½ΠΈ Π½Π΅ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°ΡŽΡ‚ΡΡ, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π½Π΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ элСмСнтами синхронизации, Π° ΠΏΡ€ΠΈ обсуТдСнии ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ Π½Π΅ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°ΡŽΡ‚ΡΡ ΠΏΠΎΡ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ здСсь Π² Π½ΠΈΡ… просто Π½Π΅Ρ‚ нСобходимости.

АтомарныС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ β€” это ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, для ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… гарантируСтся ΠΈΡ… Π½Π΅ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°Π΅ΠΌΠΎΡΡ‚ΡŒ Π΄Π°ΠΆΠ΅ ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ Π½Π° симмСтричных ΠΌΡƒΠ»ΡŒΡ‚ΠΈΠΏΡ€ΠΎΡ†Π΅ΡΡΠΎΡ€Π½Ρ‹Ρ… ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ°Ρ…. Π’Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½Ρ‹Ρ… ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ Π½Π΅ прСрываСтся Π΄Π°ΠΆΠ΅ асинхронными Π°ΠΏΠΏΠ°Ρ€Π°Ρ‚Π½Ρ‹ΠΌΠΈ прСрываниями. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, эта Π³Ρ€ΡƒΠΏΠΏΠ° ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ являСтся Ρ‚Π°ΠΊΠΆΠ΅ ΠΈ бСзопасной Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠΌ ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠΈ.

Π”Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ, Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ часто ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Ρ‹ синхронизации ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ для создания критичСской сСкции ΠΊΠΎΠ΄Π° с Ρ†Π΅Π»ΡŒΡŽ прСдотвращСния возмоТности ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ воздСйствия Π½Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… со стороны Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎ Ρ€Π°Π·Π²ΠΈΠ²Π°ΡŽΡ‰ΠΈΡ…ΡΡ Π²Π΅Ρ‚Π²Π΅ΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹.

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

Π’ ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠΉ срСдС элСмСнтарныС ΠΈ ΠΏΡ€ΠΈΠ²Ρ‹Ρ‡Π½Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Ρ‚Π°ΠΈΡ‚ΡŒ Π² сСбС опасности. Π”Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ, ΠΏΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠΈΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ Π²ΠΈΠ΄Π°:

i = i + 1;

содСрТит Π² сСбС ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒ, Ссли этот ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ записан Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠ°, выполняСмой нСсколькими экзСмплярами ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² (ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎ Ρ‚ΠΈΠΏΠΈΡ‡Π½Ρ‹ΠΉ случай). НС ΠΌΠ΅Π½Π΅Π΅ опасСн, Π½ΠΎ ΠΌΠ΅Π½Π΅Π΅ ΠΎΡ‡Π΅Π²ΠΈΠ΄Π΅Π½ ΠΏΠΎ Π²Π½Π΅ΡˆΠ½Π΅ΠΌΡƒ Π²ΠΈΠ΄Ρƒ ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€:

i += 1;

Π”Π°ΠΆΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ ΠΈΠ½ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚Π° ΠΈ Π΄Π΅ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚Π° (++i ΠΈ --i), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π² систСмС ΠΊΠΎΠΌΠ°Π½Π΄ практичСски всСх Ρ‚ΠΈΠΏΠΎΠ² процСссоров Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ ΠΊΠ°ΠΊ Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½Ρ‹Π΅ ΠΈ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ основой для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ сСмафорных ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ, Π² симмСтричной ΠΌΡƒΠ»ΡŒΡ‚ΠΈΠΏΡ€ΠΎΡ†Π΅ΡΡΠΎΡ€Π½ΠΎΠΉ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π΅ ΠΏΠ΅Ρ€Π΅ΡΡ‚Π°ΡŽΡ‚ Π±Ρ‹Ρ‚ΡŒ бСзопасными. Π₯ΡƒΠΆΠ΅ Ρ‚ΠΎΠ³ΠΎ, ΠΏΡ€ΠΈΠ²Ρ‹Ρ‡Π½Ρ‹Π΅ программисту ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ ΠΈ просто синтаксичСскиС конструкции языка становятся нСбСзопасными Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠΉ срСдС. Π’ΠΎΡ‚ Π΅Ρ‰Π΅ Π΄Π²Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°:

1. ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ копирования Π½Π΅Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ Π±Π»ΠΎΠΊΠ° памяти, бСзбоязнСнно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ дСсятилСтиями:

void* memcpy(void* dst, const void* src, size_t length);

2. ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ присваивания, ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΈΠ»ΠΈ сравнСния структурированных ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π΄Π°Π½Π½Ρ‹Ρ…:

struct X {

 X(const X& y) { ... }

 friend bool operator==(const X& f, const X& s) { ... }

 // ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ присваивания ΠΌΡ‹ Π½Π΅ пСрСопрСдСляСм, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ

 // присваиваниС ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ - ΠΏΠΎΠ±Π°ΠΉΡ‚ΠΎΠ²ΠΎΠ΅ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅

};

...

X A;

...

X B(А); // ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½Π°Ρ ошибка

...

B = A; // ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½Π°Ρ ошибка

if (А == Π’) { ... } // ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½Π°Ρ ошибка

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ всС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ…, для ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΌΠΎΠ³ΡƒΡ‚ Π½Π°Π±Π»ΡŽΠ΄Π°Ρ‚ΡŒΡΡ обсуТдаСмыС эффСкты, Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ доступны Π²Π½Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠ°, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ Π±Ρ‹Ρ‚ΡŒ Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΌΠΈ с Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния видимости Π² ΠΏΠΎΡ‚ΠΎΠΊΠ΅.

ИмСнно для бСзопасного манипулирования Π΄Π°Π½Π½Ρ‹ΠΌΠΈ Π² ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎΠΉ срСдС QNX API ΠΈ вводятся Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ. Π”Π΅ΡΡΡ‚ΡŒ Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ дСлятся Π½Π° Π΄Π²Π΅ симмСтричныС Π³Ρ€ΡƒΠΏΠΏΡ‹ ΠΏΠΎ Π²ΠΈΠ΄Ρƒ своСго имСнования ΠΈ Π»ΠΎΠ³ΠΈΠΊΠ΅ функционирования. ВсС Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²Π»ΡΡŽΡ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π°Π΄ ΠΎΠ΄Π½ΠΈΠΌ Ρ‚ΠΈΠΏΠΎΠΌ Π΄Π°Π½Π½Ρ‹Ρ… unsigned int, Π½ΠΎ, ΠΊΠ°ΠΊ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π΄Π°Π»Π΅Π΅, это Π½Π΅ Ρ‚Π°ΠΊΠΎΠ΅ ΡƒΠΆ ΠΈ сильноС ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅. Π‘Π°ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, Π½Π°Π΄ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ осущСствляСтся атомарная опСрация (Ρ‚ΠΈΠΏΠ° unsigned int), β€” это самая обычная пСрСмСнная цСлочислСнного Ρ‚ΠΈΠΏΠ°, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ описанная с ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΠΌ volatile.