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

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

Автор Π¦ΠΈΠ»ΡŽΡ€ΠΈΠΊ ОлСг Π˜Π²Π°Π½ΠΎΠ²ΠΈΡ‡

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) { ... }