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

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

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

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 Π½Π°Π·Π°Π΄ ΠΈ содСрТащСй Π² своСм Ρ‚Π΅Π»Π΅ статичСскиС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅!

POSIX.1 Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Π΅ Π² Π½Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π±Ρ‹Π»ΠΈ максимально бСзопасными Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠΉ срСдС. Но ΠΏΠ΅Ρ€Π΅Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° всСх Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ - Ρ‚Ρ€ΡƒΠ΄ΠΎΠ΅ΠΌΠΊΠΈΠΉ ΠΈ Π΄Π»ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ процСсс. API QNX (ΠΈ Ρ‚Π°ΠΊ поступили ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΠΈ ΠΌΠ½ΠΎΠ³ΠΈΡ… POSIX-совмСстимых ОБ) для ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ нСбСзопасных Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠΉ срСдС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ Π²Π²Π΅Π»ΠΈ ΠΈΡ… эквивалСнты, ΠΎΡ‚Π»ΠΈΡ‡Π°ΡŽΡ‰ΠΈΠ΅ΡΡ суффиксом Β«_rΒ», Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

localtime()
β€”
localtime_r()
,
rand()
β€”
rand_r()
ΠΈ Ρ‚.Π΄. ΠŸΡ€ΠΈΠ½Ρ†ΠΈΠΏΠΈΠ°Π»ΡŒΠ½ΠΎ нСбСзопасна Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠΉ срСдС ΠΎΠ΄Π½Π° ΠΈΠ· самых Β«Π»ΡŽΠ±ΠΈΠΌΡ‹Ρ…Β» Π² UNIX функция β€”
select()
.