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

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

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

 ...

 // ΠΌΠΎΠΆΠ½ΠΎ Π΄Π°ΠΆΠ΅ Π½Π΅ Π΄Π΅Π»Π°Ρ‚ΡŒ копию - это ΡƒΠΆΠ΅ копия:

 printf("%s", (char*)data);

}

...

while (true) {

 char *data = ... /* инициализация Π΄Π°Π½Π½Ρ‹Ρ… */;

 if ( /* Π½Π΅Ρ‡Ρ‚ΠΎ */ )

  pthread_create(NULL, &attr, &ThreadProc, strdup(data));

}

2. Для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° скалярного Ρ‚ΠΈΠΏΠ° (char, short, int), Π½Π΅ ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ°ΡŽΡ‰Π΅Π³ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€ указатСля, ΠΎΡ‡Π΅Π½ΡŒ часто Π² самых Ρ€Π°Π·Π½ΠΎΠΎΠ±Ρ€Π°Π·Π½Ρ‹Ρ… источниках [1, 3] ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ Ρ‚Π°ΠΊΠΎΠΉ Ρ‚Ρ€ΡŽΠΊ, ΠΊΠΎΠ³Π΄Π° ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŽ присваиваСтся нСпосрСдствСнноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ скалярной Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρ‹:

// функция ΠΏΠΎΡ‚ΠΎΠΊΠ°:

void* ThreadProc(void* data) {

 // ... выполняСтся ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° (char)data

 return NULL;

}


// ΠΏΠΎΡ€ΠΎΠΆΠ΄Π°ΡŽΡ‰ΠΈΠΉ ΠΏΠΎΡ‚ΠΎΠΊΠΈ ΠΊΠΎΠ΄:

while (true) {

 char data = /* инициализация ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° */;

 if ( /* ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌ Π½Π΅Ρ‡Ρ‚ΠΎ */ )

  pthread_create(NULL, &attr, &ThreadProc, (void*)data);

}

Или Π΄Π°ΠΆΠ΅ Ρ‚Π°ΠΊ:

pthread_create(NULL, &attr, &ThreadProc, (void*)5);

pthread_create(NULL, &attr, &ThreadProc, (void*)(x + y));

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

3. Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ экзСмпляра Π΄Π°Π½Π½Ρ‹Ρ… Π² Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΎΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ΅ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π½ΠΎΠ²ΠΎΠ³ΠΎ экзСмпляра создаваСмого ΠΏΠΎΡ‚ΠΎΠΊΠ° с Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ экзСмпляра Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΡ€ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°:

void* ThreadProc(void *data) {

 // ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ экзСмпляр data Π±Π΅Π· копирования ...

 ...

 delete data;

 return NULL;

}

...

if ( /* Π½Π΅Ρ‡Ρ‚ΠΎ */ ) {

 // созданиС экзСмпляра вмСстС с ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ

 // (ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅ΠΌ, Ρ‡Ρ‚ΠΎ для DataParam Ρ€Π°Π½Π΅Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½

 // ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ конструктор):

 pthread_create(NULL, &attr, &ThreadProc, new DataParam(data));

}

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

4. Β«Π ΡƒΡ‡Π½ΠΎΠΉΒ» Π²Ρ‹Π·ΠΎΠ² диспСтчСризации Π² ΠΏΠΎΡ€ΠΎΠΆΠ΄Π°ΡŽΡ‰Π΅ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ΅, ΠΏΠΎ ΠΊΡ€Π°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅Ρ€Π΅ ΠΏΡ€ΠΈ дисциплинС ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ для QNX β€” round-robin:

if ( /* Π½Π΅Ρ‡Ρ‚ΠΎ */ ) {

 pthread_create(NULL, &attr, &ThreadProc, &data);

 sched_yield();

}

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

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

Π’ этом мСстС Π²Π½ΠΈΠΌΠ°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ Ρ‡ΠΈΡ‚Π°Ρ‚Π΅Π»ΡŒ Π²ΠΏΡ€Π°Π²Π΅ ΠΎΠΆΠΈΠ²ΠΈΡ‚ΡŒΡΡ: Β«ΠžΠ±ΠΌΠ°Π½Ρ‹Π²Π°ΡŽΡ‚, ΠΎΠ±Π²Π΅ΡˆΠΈΠ²Π°ΡŽΡ‚β€¦Β». Π”Π°, описываСмоС здСсь экзотичСскоС Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π½Π΅ совсСм ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ с ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΡƒΠΆΠ΅ ΡƒΠΏΠΎΠΌΠΈΠ½Π°Π²ΡˆΠ΅Π³ΠΎΡΡ опрСдСлСния Π­. ДСйкстры «слабосвязанных процСссов» ΠΈ нСзависимости Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° ΠΎΡ‚ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… скоростСй: Π² SMP-систСмС ΠΏΡ€ΠΈ количСствС процСссоров, большСм, Ρ‡Π΅ΠΌ количСство ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², это Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Ρ‚Π°ΠΊ, ΠΊΠ°ΠΊ ΠΌΡ‹ Π΅ΠΌΡƒ прСдписываСм. Но ΠΊ настоящСму Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Ρ‚Π°ΠΊΠΎΠ΅ «стСчСниС ΠΎΠ±ΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΡΡ‚Π²Β» ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π»ΠΈΠ±ΠΎ чисто тСорСтичСски ΡƒΠΌΠΎΠ·Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ, Π»ΠΈΠ±ΠΎ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Ρ‚ΡŒ Π½Π° ΡΠΊΡΠΏΠ΅Ρ€ΠΈΠΌΠ΅Π½Ρ‚Π°Π»ΡŒΠ½Ρ‹Ρ… Π΅Π΄ΠΈΠ½ΠΈΡ‡Π½Ρ‹Ρ… ΠΎΠ±Ρ€Π°Π·Ρ†Π°Ρ… SMP, содСрТащих дСсятки ΠΈ сотни процСссоров…, Π½ΠΎ Π³Π΄Π΅ QNX, насколько Π½Π°ΠΌ извСстно, Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ.

Π’ этом Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π΅ ΠΈ Π² ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½Π½ΠΎΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ΅ ΠΌΠΎΠΆΠ½ΠΎ симмСтрично ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‚Π°ΠΊ:

void* ThreadProc(void *data) {

 struct DataParam copy(*data);

 sched_yield();

 ...

}

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

Иногда для выраТСния этой Ρ‚Π΅Ρ…Π½ΠΈΠΊΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΈ такая, Π² ΠΎΠ±Ρ‰Π΅ΠΌ нСсколько нСбрСТная, Ρ„ΠΎΡ€ΠΌΠ° записи:

pthread_create(NULL, &attr, &ThreadProc, &data);

delay(1); // вмСсто sched_yield()

Ѐокус здСсь состоит Π½Π΅ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ 1 миллисСкунда β€” это врСмя, Π·Π°Π²Π΅Π΄ΠΎΠΌΠΎ достаточноС для копирования экзСмпляра Π΄Π°Π½Π½Ρ‹Ρ…, Π° Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ POSIX опрСдСляСт, Ρ‡Ρ‚ΠΎ опСрация delay() (Π° Ρ‚Π°ΠΊΠΆΠ΅ всС родствСнныС Π΅ΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ: sleep(), nanosleep() ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ пассивной Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΈ) являСтся ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠ΅ΠΉ пассивного оТидания ΠΈ Π΄ΠΎΠ»ΠΆΠ½Π° ΡΠΎΠΏΡ€ΠΎΠ²ΠΎΠΆΠ΄Π°Ρ‚ΡŒΡΡ ΠΏΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ диспСтчСризациСй.

5. Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠ° с ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ΠΎΠΌ Π²Ρ‹ΡˆΠ΅, Ρ‡Π΅ΠΌ Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ, с ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ΠΎΠΌ Π΅Π³ΠΎ ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π° Π½Π° ΠΏΡ€Π΅ΠΆΠ½ΠΈΠΉ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ послС выполнСния Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΠΎΠΉ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΊΠΎΠΏΠΈΠΈ:

void* ThreadProc(void* data) {

 struct sched_param param;

 int policy;

 pthread_getschedparam(pthread_self(), &policy, &param);

 param.sched_priority -= 2;

 // инициализация ΠΊΠΎΠΏΠΈΠΈ Π±Π»ΠΎΠΊΠ° Π΄Π°Π½Π½Ρ‹Ρ…

 ...

 pthread_setschedparam(pthread_self(), policy, &param);

 ...

 return NULL;

}

...

if ( /* Π½Π΅Ρ‡Ρ‚ΠΎ */ ) {

 pthread_attr_t attr;

 pthread_attr_init(&attr);

 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

 pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);

 pthread_attr_setschedpolicy(&attr, SCHED_RR);

 int policy;

 struct sched_param param;

 pthread_getschedparam(pthread_self(), &policy, &param);

 attr.param.sched_priority = param.sched_priority + 2;

 pthread_create(NULL, &attr, &ThreadProc, &data);

}

Π—Π΄Π΅ΡΡŒ Π² Ρ‚ΠΎΡ‡ΠΊΠ΅ создания ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ сразу ΠΆΠ΅ вытСсняСт своСго родитСля ΠΈ выполняСт ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΊΠΎΠΏΠΈΠΈ области ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ², послС Ρ‡Π΅Π³ΠΎ возвращаСтся ΠΊ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎΠΉ (с Ρ€Π°Π²Π½Ρ‹ΠΌΠΈ ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π°ΠΌΠΈ) диспСтчСризации. Π­Ρ‚ΠΎΡ‚ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ искусствСнно услоТнСнным, Π½ΠΎ ΠΎΡ‚Π»ΠΈΡ‡Π½ΠΎ вписываСтся своими ΠΏΠΎΠ±ΠΎΡ‡Π½Ρ‹ΠΌΠΈ достоинствами Π² созданиС ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½Ρ‹Ρ… GUI-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ для графичСской подсистСмы Photon.

Π”Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠ°

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

class DataBlock {

 DataBlock(void);

 DataBlock(DataBlock&);

}


DataBlock A;


void* ThreadProc(void *data) {

 static DataBlock B;

 DataBlock C, D(*(DataBlock*)data);

 ...

 delete data;

 return NULL;

}

...

for(int i = 0; i < N; i++ ) {

 DataBlock E;

 // ... ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΈ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ E ...

 pthread_create(NULL, NULL, &ThreadProc, new DataBlock(E));

}

Π’ этом ΠΏΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠ΅ΠΌ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π΅ ΠΊΠΎΠ΄Π° N ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Ρ€Π°Π·Π΄Π΅Π»ΡΡŽΡ‚ Π΅Π΄ΠΈΠ½Ρ‹Π΅ экзСмпляры Π΄Π°Π½Π½Ρ‹Ρ… А ΠΈ Π’: Π»ΡŽΠ±Ρ‹Π΅ измСнСния, сдСланныС Π² Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ i, Π±ΡƒΠ΄ΡƒΡ‚ Π²ΠΈΠ΄ΠΈΠΌΡ‹ ΠΏΠΎΡ‚ΠΎΠΊΡƒ j, Ссли, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ, ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π° синхронизация доступа ΠΊ Π΄Π°Π½Π½Ρ‹ΠΌ ΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠΈ «совмСстными усилиями» Π½Π΅ Ρ€Π°Π·Ρ€ΡƒΡˆΠ°Ρ‚ Ρ†Π΅Π»ΠΎΡΡ‚Π½ΠΎΡΡ‚ΡŒ Π±Π»ΠΎΠΊΠ° Π΄Π°Π½Π½Ρ‹Ρ…. Π”Ρ€ΡƒΠ³ΠΈΠ΅ Π±Π»ΠΎΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ…, Π‘ ΠΈ D, прСдставлСны ΠΎΠ΄Π½ΠΈΠΌ ΠΈΠ·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ экзСмпляром Π½Π° ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ, ΠΈ Π½ΠΈΠΊΠ°ΠΊΠΈΠ΅ измСнСния, ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΠΌΡ‹Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ Π² своСм экзСмплярС Π΄Π°Π½Π½Ρ‹Ρ…, Π½Π΅ Π±ΡƒΠ΄ΡƒΡ‚ Π²ΠΈΠ΄Π½Ρ‹ Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ.

ΠŸΠΎΠ΄ΠΎΠ±Π½Ρ‹Π΅ эффСкты Π½Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‚ Π² ΠΎΠ΄Π½ΠΎΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²Ρ‹Ρ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°Ρ…, Π° Ссли ΠΎΠ½ΠΈ Π½Π΅ ΡƒΡ‡ΠΈΡ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ ΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‚ спонтанно, Ρ‚ΠΎ ΠΏΠΎΡ€ΠΎΠΆΠ΄Π°ΡŽΡ‚ ΠΊΡ€Π°ΠΉΠ½Π΅ Ρ‚Ρ€ΡƒΠ΄Π½ΠΎ выявляСмыС ошибки.[19] ΠžΡ‡Π΅Π½ΡŒ часто Ρ‚Π°ΠΊΠΈΠ΅ ошибки Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‚ послС прСобразования ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹Ρ… ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ Π² ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²Ρ‹Π΅. Рассмотрим ΠΏΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠΈΠΉ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ ΠΊΠΎΠ΄Π°:

int M = 0;


void Func_2(void) {

 static int Π‘ = 0;

 M += 2;

 C++;

 M -= 2;

}


void Func_1(void) { Func_2(); }


void* ThreadProc(void *data) {

 Func_1();

 return NULL;

}

...

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

 pthread_create(NULL, NULL, &ThreadProc, NULL);

МоТно Π»ΠΈ здСсь ΡƒΡ‚Π²Π΅Ρ€ΠΆΠ΄Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ пСрСмСнная M сохранит Π½ΡƒΠ»Π΅Π²ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π° пСрСмСнная Π‘ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ являСтся счСтчиком Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² ΠΈ Π΅Π΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ станСт N? Ни Π² ΠΊΠΎΠ΅ΠΉ ΠΌΠ΅Ρ€Π΅: послС выполнСния Ρ‚Π°ΠΊΠΎΠ³ΠΎ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π° Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ всС Ρ‡Ρ‚ΠΎ ΡƒΠ³ΠΎΠ΄Π½ΠΎ. Но Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ° Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² Func_1()->Func_2() ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ сколь ΡƒΠ³ΠΎΠ΄Π½ΠΎ Π΄Π»ΠΈΠ½Π½ΠΎΠΉ, описаниС Func_2() ΠΌΠΎΠΆΠ΅Ρ‚ Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎ Π² Π΄Ρ€ΡƒΠ³ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅ ΠΊΠΎΠ΄Π° (вмСстС с объявлСниСм ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ M!) ΠΈ, Π½Π°ΠΊΠΎΠ½Π΅Ρ†, Func_2() Π² нашСй транскрипции ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ любой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ ΠΈΠ· Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ C/C++, писавшСйся Π»Π΅Ρ‚ 15 Π½Π°Π·Π°Π΄ ΠΈ содСрТащСй Π² своСм Ρ‚Π΅Π»Π΅ статичСскиС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅!