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

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

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

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

Β // static обСспСчиваСт Π½Π΅Ρ€Π°Π·Ρ€ΡƒΡˆΠ°Π΅ΠΌΠΎΡΡ‚ΡŒ

Β static struct DataParam copy;

Β copy = data;

Β pthread_create(NULL, &attr, &ThreadProc, &copy);

}

Π­Ρ‚ΠΎΡ‚ способ ΠΈΠ½ΠΎΠ³Π΄Π° Ρ…ΠΎΡ€ΠΎΡˆΠΎ «срабатываСт» для Π΄Π°Π½Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠ° ΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹Ρ… строк, прСдставлСнных Π² стандартС языка Π‘ (ΠΎΠ΄Π½Π°ΠΊΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΎΠ½ Π½Π΅ часто):

void* ThreadProc(void *data) {

Β ...

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

Β 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()
ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ пассивной Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΈ) являСтся ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠ΅ΠΉ пассивногооТидания ΠΈ Π΄ΠΎΠ»ΠΆΠ½Π° ΡΠΎΠΏΡ€ΠΎΠ²ΠΎΠΆΠ΄Π°Ρ‚ΡŒΡΡ ΠΏΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ диспСтчСризациСй.