ΠΠ°Π»Π΅Π΅ ΡΠ»Π΅Π΄ΡΠ΅Ρ ΠΊΠΎΠ΄
SingleProc()
static pthread_key_t key;
static pthread_once_t once = PTHREAD_ONCE_INIT;
static void destructor(void* db) {
Β delete (DataBlock*)db;
}
static void once_creator(void) {
Β // ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ Π΅Π΄ΠΈΠ½ΡΠΉ Π½Π° ΠΏΡΠΎΡΠ΅ΡΡ ΠΊΠ»ΡΡ Π΄Π»Ρ Π΄Π°Π½Π½ΡΡ
DataBlock:
Β pthread_key_create(&key, destructor);
}
void* ThreadProc(void *data) {
Β // Π³Π°ΡΠ°Π½ΡΠΈΡ ΡΠΎΠ³ΠΎ, ΡΡΠΎ ΠΊΠ»ΡΡ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΡΠ΅ΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ 1 ΡΠ°Π· Π½Π° ΠΏΡΠΎΡΠ΅ΡΡ!
Β pthread_once(&once, once_creator);
Β if (pthread_getspecific(key) == NULL)
Β pthread_setspecific(key, new DataBlock(...));
Β // Π’Π΅ΠΏΠ΅ΡΡ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠ°Π· Π² ΡΠ΅Π»Π΅ ΡΡΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ ΠΈΠ»ΠΈ ΡΡΠ½ΠΊΡΠΈΠΉ, Π²ΡΠ·ΡΠ²Π°Π΅ΠΌΡΡ
Β // ΠΈΠ· Π½Π΅Π΅, ΠΌΡ Π²ΡΠ΅Π³Π΄Π° ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠ»ΡΡΠΈΡΡ Π΄ΠΎΡΡΡΠΏ ΠΊ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΡ Π΄Π°Π½Π½ΡΡ
Β DataBlock* pdb = pthread_getspecific(key);
Β // ... Π²ΡΠ΅ ΡΠ΅ ΠΆΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ Ρ ΠΏΠΎΠ»ΡΠΌΠΈ pdb->(DataBlock)
Β return NULL;
}
ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, ΡΡΠΎ Π²ΡΡ ΠΎΠΏΠΈΡΠ°Π½Π½Π°Ρ ΡΠ΅Ρ Π½ΠΈΠΊΠ° ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°Π½ΠΈΡ ΠΏΠΎΡΠΎΠΊΠΎΠ²ΡΡ ΡΡΠ½ΠΊΡΠΈΠΉ Π² ΡΠ΅Π΅Π½ΡΠ΅ΡΠ°Π±Π΅Π»ΡΠ½ΡΠ΅ (ΠΊΠ°ΠΊ ΠΈ Π²ΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΡΠ΅ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ POSIX) ΠΎΡΡΠ΅ΡΠ»ΠΈΠ²ΠΎ ΠΎΡΠΈΠ΅Π½ΡΠΈΡΠΎΠ²Π°Π½Π° Π½Π° ΡΠ΅ΠΌΠ°Π½ΡΠΈΠΊΡ ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ Π‘, Π² ΡΠΎ Π²ΡΠ΅ΠΌΡ ΠΊΠ°ΠΊ Π²ΡΠ΅ ΡΠ²ΠΎΠ΅ ΠΈΠ·Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΌΡ ΠΎΡΠΈΠ΅Π½ΡΠΈΡΡΠ΅ΠΌ ΠΈ ΠΈΠ»Π»ΡΡΡΡΠΈΡΡΠ΅ΠΌ Π½Π° Π‘++. ΠΡΠΈ ΡΠΎΠ·Π΄Π°Π½ΠΈΠΈ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ° ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΡ Π΄Π°Π½Π½ΡΡ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ ΡΠ°Π·ΡΡΡΠ°Π΅ΡΡΡ ΠΊΠΎΠ½ΡΡΠΎΠ»Ρ ΡΠΈΠΏΠΈΠ·Π°ΡΠΈΠΈ: ΡΠ°Π·Π½ΡΠ΅ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΡ ΠΏΠΎΡΠΎΠΊΠΎΠ² Π²ΠΏΠΎΠ»Π½Π΅ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ ΠΏΡΠΈΡΠ²ΠΎΠΈΡΡ ΡΠ²ΠΎΠΈΠΌ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΡΠΌ Π΄Π°Π½Π½ΡΠ΅ (ΡΠΈΠΏΠ° v
oid*
key
DataBlock_1*
DataBlock_2*
ΠΡΠΎΠ±Π°Ρ ΠΎΠ±Π»Π°ΡΡΡ, Π² ΠΊΠΎΡΠΎΡΠΎΠΉ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅ ΠΏΠΎΡΠΎΠΊΠ° ΠΌΠΎΠ³ΡΡ Π½Π°ΠΉΡΠΈ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΈ Π³Π΄Π΅ Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΠ΅ (ΡΡΠ΅ΠΊΠΎΠ²ΡΠ΅) ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΠΏΠΎΡΠΎΠΊΠ° Π½Π΅ ΠΌΠΎΠ³ΡΡ Π±ΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½Ρ, β ΡΡΠΎ Π°ΡΠΈΠ½Ρ ΡΠΎΠ½Π½ΠΎΠ΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΡΡΠ°Π³ΠΌΠ΅Π½ΡΠ° ΠΊΠΎΠ΄Π° Π² ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ΅ ΠΏΠΎΡΠΎΠΊΠ°, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ ΠΏΡΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΠΈ ΠΏΠΎΡΠΎΠΊΠΎΠΌ ΡΠΈΠ³Π½Π°Π»Π°.
ΠΡΠ΅ ΠΎΠ΄Π½ΠΎ ΡΠΎΠ²ΡΠ΅ΠΌ Π½Π΅ ΠΎΡΠ΅Π²ΠΈΠ΄Π½ΠΎΠ΅ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΡ Π΄Π°Π½Π½ΡΡ ΠΏΠΎΡΠΎΠΊΠ° (ΠΌΡ Π½Π΅ Π²ΡΡΡΠ΅ΡΠ°Π»ΠΈ Π² Π»ΠΈΡΠ΅ΡΠ°ΡΡΡΠ΅ ΡΠΏΠΎΠΌΠΈΠ½Π°Π½ΠΈΠΉ ΠΎ Π½Π΅ΠΌ), ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΎΡΠΎΠ±ΠΎ ΠΎΡΠ³Π°Π½ΠΈΡΠ½ΠΎ Π²ΠΏΠΈΡΡΠ²Π°Π΅ΡΡΡ Π² ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΈΠΌΠ΅Π½Π½ΠΎ Π‘++, β ΡΡΠΎ Π΅ΡΠ΅ ΠΎΠ΄ΠΈΠ½ ΡΠΏΠΎΡΠΎΠ± Π²ΠΎΠ·Π²ΡΠ°ΡΠ° Π² ΡΠΎΠ΄ΠΈΡΠ΅Π»ΡΡΠΊΠΈΠΉ ΠΏΠΎΡΠΎΠΊ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠ² ΡΠ°Π±ΠΎΡΡ Π΄ΠΎΡΠ΅ΡΠ½ΠΈΡ . ΠΡΠΈ ΡΡΠΎΠΌ Π½Π΅Π²Π°ΠΆΠ½ΠΎ, ΠΊΠ°ΠΊ Π±ΡΠ»ΠΈ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Ρ Π΄ΠΎΡΠ΅ΡΠ½ΠΈΠ΅ ΠΏΠΎΡΠΎΠΊΠΈ - ΠΊΠ°ΠΊ ΠΏΡΠΈΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½Π½ΡΠ΅ ΠΈΠ»ΠΈ ΠΊΠ°ΠΊ ΠΎΡΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½Π½ΡΠ΅ (ΠΌΡ ΠΎΠ±ΡΡΠΆΠ΄Π°Π»ΠΈ ΡΡΠΎ ΡΠ°Π½Π΅Π΅); ΡΠ°ΠΊΠΎΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Π² Π·Π°ΠΌΠ΅ΡΠ½ΠΎΠΉ ΠΌΠ΅ΡΠ΅ Π½ΠΈΠ²Π΅Π»ΠΈΡΡΠ΅Ρ ΠΈΡ ΡΠ°Π·Π½ΠΈΡΡ. ΠΡΠ° ΡΠ΅Ρ Π½ΠΈΠΊΠ° ΡΠΎΡΡΠΎΠΈΡ Π² ΡΠΎΠΌ, ΡΡΠΎ:
β’Β ΠΡΠ»ΠΈ ΠΏΡΠΈ ΡΠΎΠ·Π΄Π°Π½ΠΈΠΈ ΠΊΠ»ΡΡΠ° Π½Π΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΡΡ Π΄Π΅ΡΡΡΡΠΊΡΠΎΡ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ° Π΄Π°Π½Π½ΡΡ ΠΏΠΎΡΠΎΠΊΠ°
pthread_key_create(..., NULL)
β’Β ΠΡΠ»ΠΈ ΠΊ ΡΡΠΈΠΌ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ°ΠΌ Π΄Π°Π½Π½ΡΡ ΡΠΎΠ·Π΄Π°Π½Ρ Π°Π»ΡΡΠ΅ΡΠ½Π°ΡΠΈΠ²Π½ΡΠ΅ ΠΏΡΡΠΈ Π΄ΠΎΡΡΡΠΏΠ° (Π° ΠΎΠ½ΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΡΡ Π² Π»ΡΠ±ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΡΠΎΠ·Π΄Π°Π½Ρ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ±Π»Π°ΡΡΠΈ ΡΡΠΈΡ Π΄Π°Π½Π½ΡΡ Π² ΠΊΠΎΠ½Π΅ΡΠ½ΠΎΠΌ ΠΈΡΠΎΠ³Π΅ Π½ΡΠΆΠ½ΠΎ ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡΡ), ΡΠΎ Π±Π»Π°Π³ΠΎΠ΄Π°ΡΡ ΡΡΠΎΠΌΡ Π΄ΠΎΡΡΡΠΏΡ ΠΏΠΎΡΠΎΠΆΠ΄Π°ΡΡΠΈΠΉ ΠΏΠΎΡΠΎΠΊΠΈ ΠΊΠΎΠ΄ ΠΌΠΎΠΆΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΄Π°Π½Π½ΡΠ΅, Β«ΠΎΡΡΠ°Π²ΡΠΈΠ΅ΡΡΒ» ΠΊΠ°ΠΊ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΏΠΎΡΠΎΠΊΠΎΠ².
Π ΠΊΠΎΠ΄Π΅ (ΡΡΠΎ Π³ΠΎΡΠ°Π·Π΄ΠΎ Π½Π°Π³Π»ΡΠ΄Π½Π΅Π΅) ΡΡΠΎ ΠΌΠΎΠΆΠ΅Ρ Π²ΡΠ³Π»ΡΠ΄Π΅ΡΡ ΡΠ°ΠΊ (ΠΊΠΎΠ΄ Ρ Π·Π°ΠΌΠ΅ΡΠ½ΡΠΌΠΈ ΡΠΏΡΠΎΡΠ΅Π½ΠΈΡΠΌΠΈ Π²Π·ΡΡ ΠΈΠ· ΡΠ΅Π°Π»ΡΠ½ΠΎΠ³ΠΎ Π·Π°Π²Π΅ΡΡΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΏΡΠΎΠ΅ΠΊΡΠ°):
// ΠΎΠΏΠΈΡΠ°Π½ΠΈΠ΅ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ° Π΄Π°Π½Π½ΡΡ
ΠΏΠΎΡΠΎΠΊΠ°
struct throwndata {
Β ...
};
static pthread_once_t once = PTHREAD_ONCE_INIT;
static pthread_key_t key;
void createkey(void) { pthread_key_create(&key, NULL); }
// STL-ΠΎΡΠ΅ΡΠ΅Π΄Ρ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Π΅ΠΉ Π½Π° ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΡ Π΄Π°Π½Π½ΡΡ
queue<throwndata*> result;
// ΡΡΠ½ΠΊΡΠΈΡ ΠΏΠΎΡΠΎΠΊΠ°
void* GetBlock(void*) {
Β pthread_once(&once, createkey);
Β throwndata *td;
Β if ((td = (throwndata*)pthread_getspecific(key)) == NULL) {
Β td = new throwndata();
Β pthread_setspecific(key, (void*)td);
Β // Π²ΠΎΡ ΠΎΠ½ - Π°Π»ΡΡΠ΅ΡΠ½Π°ΡΠΈΠ²Π½ΡΠΉ ΠΏΡΡΡ Π΄ΠΎΡΡΡΠΏΠ°:
Β result.push(td);
Β }
Β // Π΄Π°Π»Π΅Π΅ ΠΈΠ΄Π΅Ρ ΠΏΠ»ΠΎΠ΄ΠΎΡΠ²ΠΎΡΠ½Π°Ρ ΡΠ°Π±ΠΎΡΠ° Π½Π°Π΄ Π±Π»ΠΎΠΊΠΎΠΌ Π΄Π°Π½Π½ΡΡ
*td
Β // . . . . . . . . .
}
int main(int argc, char **argv) {
Β // . . . . . .
Β for (int i = 0; i < N; i++)
Β Β pthread_create(NULL, NULL, GetBlock, NULL);
Β // . . . . . . ΠΊ ΡΡΠΎΠΌΡ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ ΠΏΠΎΡΠΎΠΊΠΈ Π·Π°Π²Π΅ΡΡΠΈΠ»ΠΈΡΡ;
Β // Π½ΠΈ Π² ΠΊΠΎΠ΅ΠΌ ΡΠ»ΡΡΠ°Π΅ Π½Π΅Π»ΡΠ·Ρ ΠΏΠΎΠΌΠ΅ΡΠ°ΡΡ result.size()
Β // Π½Π΅ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²Π΅Π½Π½ΠΎ Π² ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ ΡΠΈΠΊΠ»Π°!
Β int n = result.size();
Β for (int i = 0; i < n; i++) {
Β Β throwndata *d = result.front();
Β // ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΠΎΡΠ΅ΡΠ΅Π΄Π½ΠΎΠ³ΠΎ Π±Π»ΠΎΠΊΠ° *d ...
Β result pop();
Β delete d;
Β }
Β return EXIT_SUCCESS;
}
Π ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠΈΡ ΠΏΡΠΈΠΌΠ΅ΡΠ°Ρ ΠΊΠΎΠ΄Π° ΠΌΡ ΡΠΊΠ°Π·ΡΠ²Π°Π»ΠΈ ΡΡΠ΅ΡΠΈΠΉ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ
pthread_create()
&GetBlock
GetBlock