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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π’Π²Π΅Π΄Π΅Π½ΠΈΠ΅ Π² QNX/Neutrino 2. Руководство ΠΏΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡŽ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Π² QNX Realtime PlatformΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 13

Автор Π ΠΎΠ± ΠšΡ‘Ρ€Ρ‚Π΅Π½

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

ΠŸΠΎΡ‚ΠΎΠΊΠΈ Π² матСматичСских опСрациях

ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΈΠΌΠ΅Π΅ΠΌ Π³Ρ€Π°Ρ„ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‰ΡƒΡŽ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ трассировки Π»ΡƒΡ‡Π°. КаТдая строка растра Π½Π° экранС зависит ΠΎΡ‚ содСрТимого основной Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… (которая описываСт Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌΡƒΡŽ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΡƒ). ΠšΠ»ΡŽΡ‡Π΅Π²Ρ‹ΠΌ ΠΌΠΎΠΌΠ΅Π½Ρ‚ΠΎΠΌ здСсь являСтся Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ каТдая строка растра Π½Π΅ зависит ΠΎΡ‚ ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ…. Π­Ρ‚ΠΎ ΠΎΠ±ΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΡΡ‚Π²ΠΎ (Π½Π΅Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ строк растра) автоматичСски ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡŽ Π΄Π°Π½Π½ΠΎΠΉ Π·Π°Π΄Π°Ρ‡ΠΈ ΠΊΠ°ΠΊ ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠΉ.

НиТС ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ ΠΎΠ΄Π½ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½Ρ‹ΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚:

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

 int x1;


 ... // Π’Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ


 for (x1 = 0; x1 < num_x_lines; x1++) {

  do_one_line(x1);

 }


 ... // ВывСсти Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚


}

Π—Π΄Π΅ΡΡŒ ΠΌΡ‹ Π²ΠΈΠ΄ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΈΠ²Π½ΠΎ ΠΏΠΎ всСм значСниям рассчитаСт Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ растровыС строки.

Π’ многопроцСссорных систСмах эта ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· процСссоров. ΠŸΠΎΡ‡Π΅ΠΌΡƒ? ΠŸΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Π½Π΅ ΡƒΠΊΠ°Π·Π°Π»ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΉ систСмС Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ Ρ‡Ρ‚ΠΎ-Π»ΠΈΠ±ΠΎ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎ. ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Π°Ρ систСма Π½Π΅ Π½Π°ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ ΡƒΠΌΠ½Π°, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ ΠΈ ΡΠΊΠ°Π·Π°Ρ‚ΡŒ: Β«Π­ΠΉ, сСкундочку! Π£ нас Π΅Π΅ 4 процСссора, ΠΈ ΠΏΠΎΡ…ΠΎΠΆΠ΅, Ρ‡Ρ‚ΠΎ Ρƒ нас Ρ‚ΡƒΡ‚ нСсколько нСзависимых ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² управлСния. Π—Π°ΠΏΡƒΡ‰Ρƒ-ΠΊΠ° я это Π½Π° всСх 4 процСссорах сразу!Β»

Π’Π°ΠΊ Ρ‡Ρ‚ΠΎ это Π΄Π΅Π»ΠΎ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° (вашС Π΄Π΅Π»ΠΎ!) β€” ΡΠΎΠΎΠ±Ρ‰ΠΈΡ‚ΡŒ QNX/Neutrino, ΠΊΠ°ΠΊΠΈΠ΅ Ρ€Π°Π·Π΄Π΅Π»Ρ‹ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ слСдуСт Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎ. ΠŸΡ€ΠΎΡ‰Π΅ всСго это ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ Π±Ρ‹ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‚Π°ΠΊ:

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

 int x1;


 ... // Π’Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ


 for (x1 = 0; x1 < num_x_lines; x1++) {

  pthread_create(NULL, NULL, do_one_line, (void*)x1);

 }


 ... // ВывСсти Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚


}

Π‘ Ρ‚Π°ΠΊΠΈΠΌ ΡƒΠΏΡ€ΠΎΡ‰Π΅Π½ΠΈΠ΅ΠΌ связано мноТСство ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ. ΠŸΠ΅Ρ€Π²Π°Ρ ΠΈΠ· Π½ΠΈΡ… (ΠΈ самая Π½Π΅Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ) состоит Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ do_one_line() придСтся ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½Π° ΠΌΠΎΠ³Π»Π° Π² качСствС своСго Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ° void* вмСсто int. Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π»Π΅Π³ΠΊΠΎ ΠΈΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° привСдСния Ρ‚ΠΈΠΏΠ° (typecast).

Вторая ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° нСсколько слоТнСС. Π‘ΠΊΠ°ΠΆΠ΅ΠΌ, Ρ‡Ρ‚ΠΎ Ρ€Π°Π·Ρ€Π΅ΡˆΠ°ΡŽΡ‰Π°Ρ ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡ‚ΡŒ дисплСя, для ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π²Ρ‹ рассчитывали ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΡƒ, Π±Ρ‹Π»Π° Ρ€Π°Π²Π½Π° 1280Γ—1024. Нам ΠΏΡ€ΠΈΡˆΠ»ΠΎΡΡŒ Π±Ρ‹ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ 1280 ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²! Π’ ΠΎΠ±Ρ‰Π΅ΠΌ-Ρ‚ΠΎ, для QNX/Neutrino это Π½Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° β€” QNX/Neutrino позволяСт ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Π΄ΠΎ 32767 ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Π² ΠΎΠ΄Π½ΠΎΠΌ процСссС! Однако, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΠΌΠ΅Ρ‚ΡŒ свой ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ стСк. Если ваш стСк ΠΈΠΌΠ΅Π΅Ρ‚ Ρ€Π°Π·ΡƒΠΌΠ½Ρ‹ΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€ (скаТСм 8 Кб), эта ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° израсходуСт ΠΏΠΎΠ΄ стСк 1280Γ—8 Кб (10 ΠΌΠ΅Π³Π°Π±Π°ΠΉΡ‚!) ΠžΠ—Π£. И Ρ€Π°Π΄ΠΈ Ρ‡Π΅Π³ΠΎ? Π’ вашСй систСмС Π΅ΡΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ 4 процСссора. Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ 4 ΠΈΠ· этих 1280 ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Π±ΡƒΠ΄ΡƒΡ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ, Π° Π΄Ρ€ΡƒΠ³ΠΈΠ΅ 1276 ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Π±ΡƒΠ΄ΡƒΡ‚ ΠΎΠΆΠΈΠ΄Π°Ρ‚ΡŒ доступа ΠΊ процСссору. (Π’ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ, Π² Π΄Π°Π½Π½ΠΎΠΌ случаС пространство ΠΏΠΎΠ΄ стСк Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π΄Π΅Π»ΡΡ‚ΡŒΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎ ΠΌΠ΅Ρ€Π΅ нСобходимости. Но Ρ‚Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, это всС Ρ€Π°Π²Π½ΠΎ расходованиС рСсурсов Π²ΠΏΡƒΡΡ‚ΡƒΡŽ β€” Π΅ΡΡ‚ΡŒ вСдь Π΅Ρ‰Π΅ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΈΠ·Π΄Π΅Ρ€ΠΆΠΊΠΈ.)

Π‘ΠΎΠ»Π΅Π΅ красивым способом Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ этой Π·Π°Π΄Π°Ρ‡ΠΈ Π±Ρ‹Π»ΠΎ Π±Ρ‹ Ρ€Π°Π·Π±ΠΈΡ‚ΡŒ Π΅Π΅ Π½Π° 4 части (ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠΎΠ΄Π·Π°Π΄Π°Ρ‡Π΅ Π½Π° ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ процСссор), ΠΈ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ ΠΊΠ°ΠΆΠ΄ΡƒΡŽ Ρ‡Π°ΡΡ‚ΡŒ ΠΊΠ°ΠΊ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ:

int num_lines_per_cpu;

int num_cpus;


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

 int cpu;


 ... // Π’Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ


 // ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ число процСссоров

 num_cpus = _syspage_ptr->num_cpu;

 num_lines_per_cpu = num_x_lines / num_cpus;

 for (cpu = 0; cpu < num_cpus; cpu++) {

  pthread_create(NULL, NULL, do_one_batch, (void*)cpu);

 }



 ... // ВывСсти Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚


}


void* do_one_batch(void *c) {

 int cpu = (int)c;

 int x1;

 for (x1 = 0; x1 < num_lines_per_cpu; x1++) {

  do_line_line(x1 + cpu * num_lines_per_cpu);

 }

}

Π—Π΄Π΅ΡΡŒ ΠΌΡ‹ запускаСм Ρ‚ΠΎΠ»ΡŒΠΊΠΎ num_cpus ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ². ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ Π½Π° ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΌ процСссорС. А ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΌΡ‹ ΠΈΠΌΠ΅Π΅ΠΌ Π΄Π΅Π»ΠΎ с нСбольшим числом ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², ΠΌΡ‹ Ρ‚Π΅ΠΌ самым Π½Π΅ засоряСм ΠΏΠ°ΠΌΡΡ‚ΡŒ Π½Π΅Π½ΡƒΠΆΠ½Ρ‹ΠΌΠΈ стСками. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΈ число процСссоров ΠΏΡƒΡ‚Π΅ΠΌ разымСнования глобальной ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ β€” указатСля Π½Π° ΡΠΈΡΡ‚Π΅ΠΌΠ½ΡƒΡŽ страницу _syspage_ptr. (Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ систСмной страницы ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ Π² ΠΊΠ½ΠΈΠ³Π΅ Β«Building Embedded SystemsΒ» (поставляСтся Π² ΠΊΠΎΠΌΠΏΠ»Π΅ΠΊΡ‚Π΅ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ ΠΏΠΎ QNX/ Neutrino β€” ΠΏΡ€ΠΈΠΌ. Ρ€Π΅Π΄.) ΠΈΠ»ΠΈ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅ <sys/syspage.h>).

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ для ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ»ΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… процСссоров

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

Бинхронизация ΠΏΠΎ ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΡŽ ΠΊ ΠΌΠΎΠΌΠ΅Π½Ρ‚Ρƒ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΏΠΎΡ‚ΠΎΠΊΠ°

Π― ΡƒΠΆΠ΅ ΡƒΠΏΠΎΠΌΠΈΠ½Π°Π», Ρ‡Ρ‚ΠΎ с ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹ΠΌ Π²Ρ‹ΡˆΠ΅ ΡƒΠΏΡ€ΠΎΡ‰Π΅Π½Π½Ρ‹ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ связана масса ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ. Π’Π°ΠΊ Π²ΠΎΡ‚, Π΅Ρ‰Π΅ ΠΎΠ΄Π½Π° связанная с Π½ΠΈΠΌ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° состоит Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ функция main() сначала запускаСт Ρ†Π΅Π»Ρ‹ΠΉ Π±ΡƒΠΊΠ΅Ρ‚ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², Π° Π·Π°Ρ‚Π΅ΠΌ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅Ρ‚ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹. Но ΠΊΠ°ΠΊ функция ΡƒΠ·Π½Π°Π΅Ρ‚, ΠΊΠΎΠ³Π΄Π° ΡƒΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹?

Π—Π°ΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ main() Π·Π°Π½ΠΈΠΌΠ°Ρ‚ΡŒΡΡ опросом, Π·Π°ΠΊΠΎΠ½Ρ‡Π΅Π½Ρ‹ Π»ΠΈ вычислСния, ΠΏΡ€ΠΎΡ‚ΠΈΠ²ΠΎΡ€Π΅Ρ‡ΠΈΡ‚ самому замыслу ОБ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ.

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

 ...

 // Π—Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ ΠΏΠΎΡ‚ΠΎΠΊΠΈ, ΠΊΠ°ΠΊ Ρ€Π°Π½ΡŒΡˆΠ΅

 while (num_lines_completed < num_x_lines) {

  sleep(1);

 }

}

He Π²Π·Π΄ΡƒΠΌΠ°ΠΉΡ‚Π΅ ΠΏΠΈΡΠ°Ρ‚ΡŒ Ρ‚Π°ΠΊΠΈΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹!

Для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ этой Π·Π°Π΄Π°Ρ‡ΠΈ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ Π΄Π²Π° изящных Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ: ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ pthread_join() ΠΈ barrier_wait().

Β«ΠŸΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅Β» (joining)

Π‘Π°ΠΌΡ‹ΠΉ простой ΠΌΠ΅Ρ‚ΠΎΠ΄ синхронизации β€” это «присоСдинСниС» ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ². РСально это дСйствиС ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ.

ΠŸΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ выполняСтся ΠΎΠ΄Π½ΠΈΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ, ΠΆΠ΄ΡƒΡ‰ΠΈΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°. Π–Π΄ΡƒΡ‰ΠΈΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ pthread_join():

#include <pthread.h>


int pthread_join(pthread_t thread, void **value_ptr);

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

Π“Π΄Π΅ Π½Π°ΠΌ Π±Ρ€Π°Ρ‚ΡŒ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ ΠΏΠΎΡ‚ΠΎΠΊΠ°? ΠœΡ‹ ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Π»ΠΈ Π΅Π³ΠΎ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pthread_create(), ΠΏΠ΅Ρ€Π΅Π΄Π°Π² NULL Π² качСствС ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°. Π”Π°Π²Π°ΠΉΡ‚Π΅ исправим Π½Π°ΡˆΡƒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ:

int num_lines_per_cpu;

int num_cpus;


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

 int cpu;

 pthread_t *thread_ids;


 ... // Π’Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ


 thread_ids = malloc(sizeof(pthread_t) * num_cpus);

 num_lines_per_cpu = num_x_lines / num_cpus;

 for (cpu = 0; cpu < num_cpus; cpu++) {

  pthread_create(

   &thread_ids[cpu], NULL, do_one_batch, (void*)cpu);

 }

 // Π‘ΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ с Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ΠΌ всСх ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²

 for (cpu = 0; cpu < num_cpus; cpu++) {

  pthread_join(thread_ids[cpu], NULL);

 }


 ... // ВывСсти Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚


}

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ Π½Π° этот Ρ€Π°Π· ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π»ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pthread_create() Π² качСствС ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° pthread_t. Π’Π°ΠΌ ΠΈ Π±ΡƒΠ΄Π΅Ρ‚ сохранСн ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ вновь созданного ΠΏΠΎΡ‚ΠΎΠΊΠ°. ПослС Ρ‚ΠΎΠ³ΠΎ ΠΊΠ°ΠΊ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ Ρ†ΠΈΠΊΠ» for Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡΡ, Ρƒ нас Π±ΡƒΠ΄Π΅Ρ‚ num_cpu Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², плюс ΠΏΠΎΡ‚ΠΎΠΊ, Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‰ΠΈΠΉ main(). ΠŸΠΎΡ‚Ρ€Π΅Π±Π»Π΅Π½ΠΈΠ΅ рСсурсов процСссора ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ main() нас ΠΌΠ°Π»ΠΎ интСрСсуСт β€” этот ΠΏΠΎΡ‚ΠΎΠΊ ΠΏΠΎΡ‚Ρ€Π°Ρ‚ΠΈΡ‚ всС своС врСмя Π½Π° ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅.

ОТиданиС достигаСтся ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pthread_join() ΠΊ ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ ΠΈΠ· Π½Π°ΡˆΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ². Π‘Π½Π°Ρ‡Π°Π»Π° ΠΌΡ‹ ΠΆΠ΄Π΅ΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΏΠΎΡ‚ΠΎΠΊΠ° thread_ids[0]. Когда ΠΎΠ½ Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡΡ, функция pthread_join() разблокируСтся. Π‘Π»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ итСрация Ρ†ΠΈΠΊΠ»Π° for заставит нас ΠΆΠ΄Π°Ρ‚ΡŒ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΏΠΎΡ‚ΠΎΠΊΠ° thread_ids[1], ΠΈ Ρ‚Π°ΠΊ Π΄Π°Π»Π΅Π΅ для всСх num_cpus ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ².

Π’ этот ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ Π·Π°ΠΊΠΎΠ½Π½Ρ‹ΠΉ вопрос: «А Ρ‡Ρ‚ΠΎ Ссли ΠΏΠΎΡ‚ΠΎΠΊΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠ°Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ Π² ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠΌ порядкС?Β» Π”Ρ€ΡƒΠ³ΠΈΠΌΠΈ словами, Ссли ΠΈΠΌΠ΅ΡŽΡ‚ΡΡ 4 процСссора, ΠΈ ΠΏΠΎ ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π΅ ΠΏΠΎΡ‚ΠΎΠΊ, Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‰ΠΈΠΉΡΡ Π½Π° послСднСм процСссорС (с Π½ΠΎΠΌΠ΅Ρ€ΠΎΠΌ 3), Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΏΠ΅Ρ€Π²Ρ‹ΠΌ, Π·Π°Ρ‚Π΅ΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡΡ ΠΏΠΎΡ‚ΠΎΠΊ, Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‰ΠΈΠΉΡΡ Π½Π° процСссорС с Π½ΠΎΠΌΠ΅Ρ€ΠΎΠΌ 2, ΠΈ Ρ‚Π°ΠΊ Π΄Π°Π»Π΅Π΅? Вся ΠΏΡ€Π΅Π»Π΅ΡΡ‚ΡŒ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΉ схСмы Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π½ΠΈΡ‡Π΅Π³ΠΎ ΠΏΠ»ΠΎΡ…ΠΎΠ³ΠΎ Π½Π΅ ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ‚.