ΠΠΎ Π²Π΅ΡΠ½Π΅ΠΌΡΡ ΠΊ Π½Π°ΡΠ΅ΠΌΡ ΠΏΡΠΈΠΌΠ΅ΡΡ. ΠΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°ΡΡ ΡΠ°ΠΊ, ΡΡΠΎΠ±Ρ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΠ΅ΠΌΠ°ΡΠΎΡΠ° ΠΏΠΎΡΠΎΠΊΠΎΠ²Π°Ρ ΡΡΠ½ΠΊΡΠΈΡ ΠΏΡΠΎΠ²Π΅ΡΡΠ»Π°, ΡΠΊΠΎΠ»ΡΠΊΠΎ Π·Π°Π΄Π°Π½ΠΈΠΉ Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ Π² ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ. ΠΠ·ΠΌΠ΅Π½Π΅Π½Π½Π°Ρ Π²Π΅ΡΡΠΈΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½Π° Π² Π»ΠΈΡΡΠΈΠ½Π³Π΅ 4.12.
ΠΠΈΡΡΠΈΠ½Π³ 4.12. (job-queue3.c) Π Π°Π±ΠΎΡΠ° Ρ ΠΎΡΠ΅ΡΠ΅Π΄ΡΡ Π·Π°Π΄Π°Π½ΠΈΠΉ Ρ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ ΡΠ΅ΠΌΠ°ΡΠΎΡΠ°#include <malloc.h>
#include <pthread.h>
#include <semaphore.h>
struct job {
/* Π‘ΡΡΠ»ΠΊΠ° Π½Π° ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΡΠ»Π΅ΠΌΠ΅Π½Ρ ΡΠ²ΡΠ·Π°Π½Π½ΠΎΠ³ΠΎ ΡΠΏΠΈΡΠΊΠ°. */
struct job* next;
/* ΠΡΡΠ³ΠΈΠ΅ ΠΏΠΎΠ»Ρ, ΠΎΠΏΠΈΡΡΠ²Π°ΡΡΠΈΠ΅ ΡΡΠ΅Π±ΡΠ΅ΠΌΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ... */
};
/* Π‘ΠΏΠΈΡΠΎΠΊ ΠΎΡΠ»ΠΎΠΆΠ΅Π½Π½ΡΡ Π·Π°Π΄Π°Π½ΠΈΠΉ. */
struct job* job_queue;
/* ΠΡΠΊΠ»ΡΡΠ°ΡΡΠΈΠΉ ΡΠ΅ΠΌΠ°ΡΠΎΡ, Π·Π°ΡΠΈΡΠ°ΡΡΠΈΠΉ ΠΎΡΠ΅ΡΠ΅Π΄Ρ. */
pthread_mutex_t job_queue_mutex =
PTHREAD_MUTEX_INITIALIZER;
/* Π‘Π΅ΠΌΠ°ΡΠΎΡ, ΠΏΠΎΠ΄ΡΡΠΈΡΡΠ²Π°ΡΡΠΈΠΉ ΡΠΈΡΠ»ΠΎ Π³Π°Π΄Π°Π½ΠΈΠΉ Π² ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ. */
sem_t job_queue_count;
/* ΠΠ°ΡΠ°Π»ΡΠ½Π°Ρ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ. */
void initialize_job_queue() {
/* ΠΠ½Π°ΡΠ°Π»Π΅ ΠΎΡΠ΅ΡΠ΅Π΄Ρ ΠΏΡΡΡΠ°. */
job_queue = NULL;
/* Π£ΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ Π½Π°ΡΠ°Π»ΡΠ½ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΡΠ΅ΡΡΠΈΠΊΠ° ΡΠ΅ΠΌΠ°ΡΠΎΡΠ°
ΡΠ°Π²Π½ΡΠΌ 0. */
sem_init(&job_queue_count, 0, 0);
}
/* ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° Π·Π°Π΄Π°Π½ΠΈΠΉ Π΄ΠΎ ΡΠ΅Ρ ΠΏΠΎΡ, ΠΏΠΎΠΊΠ° ΠΎΡΠ΅ΡΠ΅Π΄Ρ Π½Π΅ ΠΎΠΏΡΡΡΠ΅Π΅Ρ. */
void* thread_function(void* arg) {
while (1) {
struct job* next_job;
/* ΠΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΡΡ Π³ΠΎΡΠΎΠ²Π½ΠΎΡΡΠΈ ΡΠ΅ΠΌΠ°ΡΠΎΡΠ°. ΠΡΠ»ΠΈ Π΅Π³ΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π±ΠΎΠ»ΡΡΠ΅
Π½ΡΠ»Ρ, Π·Π½Π°ΡΠΈΡ, ΠΎΡΠ΅ΡΠ΅Π΄Ρ Π½Π΅ ΠΏΡΡΡΠ°; ΡΠΌΠ΅Π½ΡΡΠ°Π΅ΠΌ ΡΡΠ΅ΡΡΠΈΠΊ Π½Π° 1.
Π ΠΏΡΠΎΡΠΈΠ²Π½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ Π±Π»ΠΎΠΊΠΈΡΡΠ΅ΡΡΡ Π΄ΠΎ ΡΠ΅Ρ ΠΏΠΎΡ, ΠΏΠΎΠΊΠ°
Π² ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ Π½Π΅ ΠΏΠΎΡΠ²ΠΈΡΡΡ Π½ΠΎΠ²ΠΎΠ΅ Π·Π°Π΄Π°Π½ΠΈΠ΅. */
sem_wait(&job_queue_count);
/* ΠΠ°Ρ Π²Π°Ρ ΠΈΡΠΊΠ»ΡΡΠ°ΡΡΠ΅Π³ΠΎ ΡΠ΅ΠΌΠ°ΡΠΎΡΠ°, Π·Π°ΡΠΈΡΠ°ΡΡΠ΅Π³ΠΎ ΠΎΡΠ΅ΡΠ΅Π΄Ρ. */
pthread_mutex_lock(&job_queue_mutex);
/* ΠΡ ΡΠΆΠ΅ Π·Π½Π°Π΅ΠΌ, ΡΡΠΎ ΠΎΡΠ΅ΡΠ΅Π΄Ρ Π½Π΅ ΠΏΡΡΡΠ°, ΠΏΠΎΡΡΠΎΠΌΡ Π±Π΅Π· Π»ΠΈΡΠ½Π΅ΠΉ
ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ Π·Π°ΠΏΡΠ°ΡΠΈΠ²Π°Π΅ΠΌ Π½ΠΎΠ²ΠΎΠ΅ Π·Π°Π΄Π°Π½ΠΈΠ΅. */
next_job = job_queue;
/* Π£Π΄Π°Π»ΡΠ΅ΠΌ Π·Π°Π΄Π°Π½ΠΈΠ΅ ΠΈΠ· ΡΠΏΠΈΡΠΊΠ°. */
job_queue = job_queue->next;
/* ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Π΅ΠΌ ΠΈΡΠΊΠ»ΡΡΠ°ΡΡΠΈΠΉ ΡΠ΅ΠΌΠ°ΡΠΎΡ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΡΠ°Π±ΠΎΡΠ° Ρ
ΠΎΡΠ΅ΡΠ΅Π΄ΡΡ ΠΎΠΊΠΎΠ½ΡΠ΅Π½Π°. */
pthread_mutex_unlock(&job_queue_mutex);
/* ΠΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌ Π·Π°Π΄Π°Π½ΠΈΠ΅. */
process_job(next_job);
/* ΠΡΠΈΡΡΠΊΠ°. */
free(next_job);
}
return NULL;
}
/* ΠΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ Π·Π°Π΄Π°Π½ΠΈΡ Π² Π½Π°ΡΠ°Π»ΠΎ ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ. */
void enqueue_job(/* ΠΠ΅ΡΠ΅Π΄Π°ΡΠ° Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΡ Π΄Π°Π½Π½ΡΡ ... */) {
struct job* new_job;
/* ΠΡΠ΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΏΠ°ΠΌΡΡΠΈ Π΄Π»Ρ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠ° Π·Π°Π΄Π°Π½ΠΈΡ. */
new_job = (struct job*)malloc(sizeof(struct job));
/* ΠΠ°ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΎΡΡΠ°Π»ΡΠ½ΡΡ ΠΏΠΎΠ»Π΅ΠΉ ΡΡΡΡΠΊΡΡΡΡ JOB... */
/* ΠΠ°Ρ Π²Π°ΡΡΠ²Π°Π΅ΠΌ ΠΈΡΠΊΠ»ΡΡΠ°ΡΡΠΈΠΉ ΡΠ΅ΠΌΠ°ΡΠΎΡ, ΠΏΡΠ΅ΠΆΠ΄Π΅ ΡΠ΅ΠΌ ΠΎΠ±ΡΠ°ΡΠΈΡΡΡΡ
ΠΊ ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ. */
pthread_mutex_lock(&job_queue_mutex);
/* ΠΠΎΠΌΠ΅ΡΠ°Π΅ΠΌ Π½ΠΎΠ²ΠΎΠ΅ Π·Π°Π΄Π°Π½ΠΈΠ΅ Π² Π½Π°ΡΠ°Π»ΠΎ ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ. */
new_job->next = job_queue;
job_queue = new_job;
/* Π£ΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ ΡΠ΅ΠΌΠ°ΡΠΎΡ, ΡΠΎΠΎΠ±ΡΠ°Ρ ΠΎ ΡΠΎΠΌ, ΡΡΠΎ Π² ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ ΠΏΠΎΡΠ²ΠΈΠ»ΠΎΡΡ
Π½ΠΎΠ²ΠΎΠ΅ Π·Π°Π΄Π°Π½ΠΈΠ΅. ΠΡΠ»ΠΈ Π΅ΡΡΡ ΠΏΠΎΡΠΎΠΊΠΈ, Π·Π°Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°Π½Π½ΡΠ΅ Π² ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠΈ
ΡΠ΅ΠΌΠ°ΡΠΎΡΠ°, ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π½ΠΈΡ Π±ΡΠ΄Π΅Ρ ΡΠ°Π·Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°Π½ ΠΈ
ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°Π΅Ρ Π·Π°Π΄Π°Π½ΠΈΠ΅. */
sem_post(&job_queue_count);
/* ΠΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Π΅ΠΌ ΠΈΡΠΊΠ»ΡΡΠ°ΡΡΠΈΠΉ ΡΠ΅ΠΌΠ°ΡΠΎΡ. */
pthread_mutex_unlock(&job_queue_mutex);
}
ΠΡΠ΅ΠΆΠ΄Π΅ ΡΠ΅ΠΌ ΠΈΠ·Π²Π»Π΅ΠΊΠ°ΡΡ Π·Π°Π΄Π°Π½ΠΈΠ΅ ΠΈΠ· ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ, ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΏΠΎΡΠΎΠΊ Π΄ΠΎΠΆΠΈΠ΄Π°Π΅ΡΡΡ ΡΠ΅ΠΌΠ°ΡΠΎΡΠ°. ΠΡΠ»ΠΈ ΡΡΠ΅ΡΡΠΈΠΊ ΡΠ΅ΠΌΠ°ΡΠΎΡΠ° ΡΠ°Π²Π΅Π½ Π½ΡΠ»Ρ, Ρ.Π΅. ΠΎΡΠ΅ΡΠ΅Π΄Ρ ΠΏΡΡΡΠ°, ΠΏΠΎΡΠΎΠΊ Π±Π»ΠΎΠΊΠΈΡΡΠ΅ΡΡΡ Π΄ΠΎ ΡΠ΅Ρ ΠΏΠΎΡ, ΠΏΠΎΠΊΠ° Π² ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ Π½Π΅ ΠΏΠΎΡΠ²ΠΈΡΡΡ Π½ΠΎΠ²ΠΎΠ΅ Π·Π°Π΄Π°Π½ΠΈΠ΅ ΠΈ ΡΡΠ΅ΡΡΠΈΠΊ Π½Π΅ ΡΡΠ°Π½Π΅Ρ ΠΏΠΎΠ»ΠΎΠΆΠΈΡΠ΅Π»ΡΠ½ΡΠΌ.
Π€ΡΠ½ΠΊΡΠΈΡ enqueue_job() Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅Ρ Π½ΠΎΠ²ΠΎΠ΅ Π·Π°Π΄Π°Π½ΠΈΠ΅ Π² ΠΎΡΠ΅ΡΠ΅Π΄Ρ. ΠΠΎΠ΄ΠΎΠ±Π½ΠΎ ΠΏΠΎΡΠΎΠΊΠΎΠ²ΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ, ΠΎΠ½Π° Π·Π°Ρ Π²Π°ΡΡΠ²Π°Π΅Ρ ΠΈΡΠΊΠ»ΡΡΠ°ΡΡΠΈΠΉ ΡΠ΅ΠΌΠ°ΡΠΎΡ, ΠΏΠ΅ΡΠ΅Π΄ ΡΠ΅ΠΌ ΠΊΠ°ΠΊ ΠΎΠ±ΡΠ°ΡΠΈΡΡΡΡ ΠΊ ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ. ΠΠΎΡΠ»Π΅ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΡ Π·Π°Π΄Π°Π½ΠΈΡ ΡΡΠ½ΠΊΡΠΈΡ enqueue_job() ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅Ρ ΡΠ΅ΠΌΠ°ΡΠΎΡ, ΡΠΎΠΎΠ±ΡΠ°Ρ ΠΏΠΎΡΠΎΠΊΠ°ΠΌ ΠΎ ΡΠΎΠΌ, ΡΡΠΎ Π·Π°Π΄Π°Π½ΠΈΠ΅ Π΄ΠΎΡΡΡΠΏΠ½ΠΎ. Π ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ΅, ΠΏΠΎΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ Π² Π»ΠΈΡΡΠΈΠ½Π³Π΅ 4.12, ΠΏΠΎΡΠΎΠΊΠΈ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π·Π°Π²Π΅ΡΡΠ°ΡΡΡΡ: Π΅ΡΠ»ΠΈ Π·Π°Π΄Π°Π½ΠΈΡ Π½Π΅ ΠΏΠΎΡΡΡΠΏΠ°ΡΡ Π² ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ Π΄Π»ΠΈΡΠ΅Π»ΡΠ½ΠΎΠ³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ, Π²ΡΠ΅ ΠΏΠΎΡΠΎΠΊΠΈ ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄ΡΡΡΡ Π² ΡΠ΅ΠΆΠΈΠΌ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΡΡΠ½ΠΊΡΠΈΠ΅ΠΉ sem_wait().
4.4.6. Π‘ΠΈΠ³Π½Π°Π»ΡΠ½ΡΠ΅ (ΡΡΠ»ΠΎΠ²Π½ΡΠ΅) ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅
ΠΡ ΡΠ·Π½Π°Π»ΠΈ, ΠΊΠ°ΠΊ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΈΡΠΊΠ»ΡΡΠ°ΡΡΠ΅Π³ΠΎ ΡΠ΅ΠΌΠ°ΡΠΎΡΠ° Π·Π°ΡΠΈΡΠΈΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ ΠΎΡ ΠΎΠ΄Π½ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ Π΄ΠΎΡΡΡΠΏΠ° ΡΠΎ ΡΡΠΎΡΠΎΠ½Ρ Π΄Π²ΡΡ ΠΈ Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΡΠΎΠΊΠΎΠ² ΠΈ ΠΊΠ°ΠΊ ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²ΠΎΠΌ ΠΎΠ±ΡΡΠ½ΠΎΠ³ΠΎ ΡΠ΅ΠΌΠ°ΡΠΎΡΠ° ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ ΡΡΠ΅ΡΡΠΈΠΊ ΠΎΠ±ΡΠ°ΡΠ΅Π½ΠΈΠΉ, Π΄ΠΎΡΡΡΠΏΠ½ΡΠΉ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΠΌ ΠΏΠΎΡΠΎΠΊΠ°ΠΌ. Π‘ΠΈΠ³Π½Π°Π»ΡΠ½Π°Ρ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ (Π½Π°Π·ΡΠ²Π°Π΅ΠΌΠ°Ρ ΡΠ°ΠΊΠΆΠ΅ ΡΡΠ»ΠΎΠ²Π½ΠΎΠΉ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ) β ΡΡΠΎ ΡΡΠ΅ΡΠΈΠΉ ΡΠ»Π΅ΠΌΠ΅Π½Ρ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠΈ Π² Linux. ΠΠ»Π°Π³ΠΎΠ΄Π°ΡΡ Π΅ΠΌΡ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Π΄Π°Π²Π°ΡΡ Π±ΠΎΠ»Π΅Π΅ ΡΠ»ΠΎΠΆΠ½ΡΠ΅ ΡΡΠ»ΠΎΠ²ΠΈΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΏΠΎΡΠΎΠΊΠΎΠ².
ΠΡΠ΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, ΡΡΠ΅Π±ΡΠ΅ΡΡΡ Π½Π°ΠΏΠΈΡΠ°ΡΡ ΠΏΠΎΡΠΎΠΊΠΎΠ²ΡΡ ΡΡΠ½ΠΊΡΠΈΡ, ΠΊΠΎΡΠΎΡΠ°Ρ Π²Ρ ΠΎΠ΄ΠΈΡ Π² Π±Π΅ΡΠΊΠΎΠ½Π΅ΡΠ½ΡΠΉ ΡΠΈΠΊΠ», Π²ΡΠΏΠΎΠ»Π½ΡΡ Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΈΡΠ΅ΡΠ°ΡΠΈΠΈ ΠΊΠ°ΠΊΠΈΠ΅-ΡΠΎ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ. ΠΠΎ ΡΠ°Π±ΠΎΡΠ° ΡΠΈΠΊΠ»Π° Π΄ΠΎΠ»ΠΆΠ½Π° ΠΊΠΎΠ½ΡΡΠΎΠ»ΠΈΡΠΎΠ²Π°ΡΡΡΡ ΡΠ»Π°Π³ΠΎΠΌ: Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ Π² ΡΠΎΠΌ ΡΠ»ΡΡΠ°Π΅, ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½.
Π Π»ΠΈΡΡΠΈΠ½Π³Π΅ 4.13 ΠΏΠΎΠΊΠ°Π·Π°Π½ Π²Π°ΡΠΈΠ°Π½Ρ ΡΠ°ΠΊΠΎΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ. ΠΠ° ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΈΡΠ΅ΡΠ°ΡΠΈΠΈ ΡΠΈΠΊΠ»Π° ΠΏΠΎΡΠΎΠΊΠΎΠ²Π°Ρ ΡΡΠ½ΠΊΡΠΈΡ ΠΏΡΠΎΠ²Π΅ΡΡΠ΅Ρ, ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½ Π»ΠΈ ΡΠ»Π°Π³. ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΊ ΡΠ»Π°Π³Ρ ΠΎΠ±ΡΠ°ΡΠ°Π΅ΡΡΡ ΡΡΠ°Π·Ρ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΏΠΎΡΠΎΠΊΠΎΠ², ΠΎΠ½ Π·Π°ΡΠΈΡΠ°Π΅ΡΡΡ ΠΈΡΠΊΠ»ΡΡΠ°ΡΡΠΈΠΌ ΡΠ΅ΠΌΠ°ΡΠΎΡΠΎΠΌ. ΠΠΎΠ΄ΠΎΠ±Π½Π°Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎΠΉ, Π½ΠΎ ΠΎΠ½Π° Π½Π΅ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½Π°. ΠΡΠ»ΠΈ ΡΠ»Π°Π³ Π½Π΅ ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½, ΠΏΠΎΡΠΎΠΊΠΎΠ²Π°Ρ ΡΡΠ½ΠΊΡΠΈΡ Π±ΡΠ΄Π΅Ρ Π²ΠΏΡΡΡΡΡ ΡΡΠ°ΡΠΈΡΡ ΡΠ΅ΡΡΡΡΡ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠ°, Π·Π°Π½ΠΈΠΌΠ°ΡΡΡ Π±Π΅ΡΡΠ΅Π»ΡΠ½ΡΠΌΠΈ ΠΏΡΠΎΠ²Π΅ΡΠΊΠ°ΠΌΠΈ ΡΠ»Π°Π³Π°, Π° ΡΠ°ΠΊΠΆΠ΅ Π·Π°Ρ Π²Π°ΡΡΠ²Π°Ρ ΠΈ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Ρ ΡΠ΅ΠΌΠ°ΡΠΎΡ. ΠΠ° ΡΠ°ΠΌΠΎΠΌ Π΄Π΅Π»Π΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΊΠ°ΠΊ-ΡΠΎ ΠΏΠ΅ΡΠ΅Π²Π΅ΡΡΠΈ ΡΡΠ½ΠΊΡΠΈΡ Π² Π½Π΅Π°ΠΊΡΠΈΠ²Π½ΡΠΉ ΡΠ΅ΠΆΠΈΠΌ, ΠΏΠΎΠΊΠ° ΠΊΠ°ΠΊΠΎΠΉ-Π½ΠΈΠ±ΡΠ΄Ρ Π΄ΡΡΠ³ΠΎΠΉ ΠΏΠΎΡΠΎΠΊ Π½Π΅ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡ ΡΡΠΎΡ ΡΠ»Π°Π³.
ΠΠΈΡΡΠΈΠ½Π³ 4.15. (spin-condvar.c) ΠΡΠΎΡΡΠ΅ΠΉΡΠ°Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΡΠΈΠ³Π½Π°Π»ΡΠ½ΠΎΠΉ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ#include <pthread.h>
int thread_flag;
pthread_mutex_t thread_flag_mutex;
void initialize_flag() {
pthread_mutex_init(&thread_flag_mutex, NULL);
thread_flag = 0;
}
/* ΠΡΠ»ΠΈ ΡΠ»Π°Π³ ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½, ΠΌΠ½ΠΎΠ³ΠΎΠΊΡΠ°ΡΠ½ΠΎ Π²ΡΠ·ΡΠ²Π°Π΅ΡΡΡ ΡΡΠ½ΠΊΡΠΈΡ do_work().
Π ΠΏΡΠΎΡΠΈΠ²Π½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΡΠΈΠΊΠ» ΡΠ°Π±ΠΎΡΠ°Π΅Ρ Π²Ρ ΠΎΠ»ΠΎΡΡΡΡ. */
void* thread_function(void* thread_arg) {
while (1) {
int flag_is_set;
/* ΠΠ°ΡΠΈΡΠ°Π΅ΠΌ ΡΠ»Π°Π³ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΈΡΠΊΠ»ΡΡΠ°ΡΡΠ΅Π³ΠΎ ΡΠ΅ΠΌΠ°ΡΠΎΡΠ°. */
pthread_mutex_lock(&thread_flag_mutex);
flag_is_set = thread_flag;
pthread_mutex_unlock(&thread_flag_mutex);
if (flag_is_set)
do_work();
/* ΠΡΠ»ΠΈ ΡΠ»Π°Π³ Π½Π΅ ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½, Π½ΠΈΡΠ΅Π³ΠΎ Π½Π΅ Π΄Π΅Π»Π°Π΅ΠΌ. ΠΡΠΎΡΡΠΎ ΠΏΠ΅ΡΠ΅Ρ ΠΎΠ΄ΠΈΠΌ
Π½Π° ΡΠ»Π΅Π΄ΡΡΡΡΡ ΠΈΡΠ΅ΡΠ°ΡΠΈΡ ΡΠΈΠΊΠ»Π°. */
}
return NULL;
}
/* ΠΠ°Π΄Π°Π΅ΠΌ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΠ»Π°Π³Π° ΡΠ°Π²Π½ΡΠΌ FLAG_VALUE. */
void set_thread_flag(int flag_value) {
/* ΠΠ°ΡΠΈΡΠ°Π΅ΠΌ ΡΠ»Π°Π³ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΈΡΠΊΠ»ΡΡΠ°ΡΡΠ΅Π³ΠΎ ΡΠ΅ΠΌΠ°ΡΠΎΡΠ°. */
pthread_mutex_lock(&thread_flag_mutex);
thread_flag = flag_value;
pthread_mutex_unlock(&thread_flag_mutex);
}
Π‘ΠΈΠ³Π½Π°Π»ΡΠ½Π°Ρ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΎΡΠ³Π°Π½ΠΈΠ·ΠΎΠ²Π°ΡΡ ΡΠ°ΠΊΡΡ ΠΏΡΠΎΠ²Π΅ΡΠΊΡ, ΠΏΡΠΈ ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΏΠΎΡΠΎΠΊ Π»ΠΈΠ±ΠΎ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ, Π»ΠΈΠ±ΠΎ Π±Π»ΠΎΠΊΠΈΡΡΠ΅ΡΡΡ. ΠΠ°ΠΊ ΠΈ Π² ΡΠ»ΡΡΠ°Π΅ ΡΠ΅ΠΌΠ°ΡΠΎΡΠ°, ΠΏΠΎΡΠΎΠΊ ΠΌΠΎΠΆΠ΅Ρ ΠΎΠΆΠΈΠ΄Π°ΡΡ ΡΠΈΠ³Π½Π°Π»ΡΠ½ΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ. ΠΠΎΡΠΎΠΊ A, Π½Π°Ρ ΠΎΠ΄ΡΡΠΈΠΉΡΡ Π² ΡΠ΅ΠΆΠΈΠΌΠ΅ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΡ, Π±Π»ΠΎΠΊΠΈΡΡΠ΅ΡΡΡ Π΄ΠΎ ΡΠ΅Ρ ΠΏΠΎΡ, ΠΏΠΎΠΊΠ° Π΄ΡΡΠ³ΠΎΠΉ ΠΏΠΎΡΠΎΠΊ. Π, Π½Π΅ ΠΏΡΠΎΡΠΈΠ³Π½Π°Π»ΠΈΠ·ΠΈΡΡΠ΅Ρ ΠΎΠ± ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ ΡΡΠΎΠΉ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ. Π‘ΠΈΠ³Π½Π°Π»ΡΠ½Π°Ρ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ Π²Π½ΡΡΡΠ΅Π½Π½Π΅Π³ΠΎ ΡΡΠ΅ΡΡΠΈΠΊΠ°, ΡΡΠΎ ΠΎΡΠ»ΠΈΡΠ°Π΅Ρ Π΅Π΅ ΠΎΡ ΡΠ΅ΠΌΠ°ΡΠΎΡΠ°. ΠΠΎΡΠΎΠΊ Π Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΠ΅ΡΠ΅ΠΉΡΠΈ Π² ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΡ Π΄ΠΎ ΡΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΏΠΎΡΠΎΠΊ Π ΠΏΠΎΡΠ»Π΅Ρ ΡΠΈΠ³Π½Π°Π». ΠΡΠ»ΠΈ ΡΠΈΠ³Π½Π°Π» Π±ΡΠ΄Π΅Ρ ΠΏΠΎΡΠ»Π°Π» ΡΠ°Π½ΡΡΠ΅, ΠΎΠ½ ΠΎΠΊΠ°ΠΆΠ΅ΡΡΡ ΠΏΠΎΡΠ΅ΡΡΠ½Π½ΡΠΌ ΠΈ ΠΏΠΎΡΠΎΠΊ Π Π·Π°Π±Π»ΠΎΠΊΠΈΡΡΠ΅ΡΡΡ, ΠΏΠΎΠΊΠ° ΠΊΠ°ΠΊΠΎΠΉ-Π½ΠΈΠ±ΡΠ΄Ρ ΠΏΠΎΡΠΎΠΊ Π½Π΅ ΠΏΠΎΡΠ»Π΅Ρ ΡΠΈΠ³Π½Π°Π» Π΅ΡΠ΅ ΡΠ°Π·.
ΠΠΎΡ ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°ΡΡ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π±ΠΎΠ»Π΅Π΅ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎΠΉ.
β Π€ΡΠ½ΠΊΡΠΈΡ thread_function() Π² ΡΠΈΠΊΠ»Π΅ ΠΏΡΠΎΠ²Π΅ΡΡΠ΅Ρ ΡΠ»Π°Π³. ΠΡΠ»ΠΈ ΠΎΠ½ Π½Π΅ ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½, ΠΏΠΎΡΠΎΠΊ ΠΏΠ΅ΡΠ΅Ρ ΠΎΠ΄ΠΈΡ Π² ΡΠ΅ΠΆΠΈΠΌ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΡ ΡΠΈΠ³Π½Π°Π»ΡΠ½ΠΎΠΉ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ.
β Π€ΡΠ½ΠΊΡΠΈΡ set_thread_flag() ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅Ρ ΡΠ»Π°Π³ ΠΈ ΡΠΈΠ³Π½Π°Π»ΠΈΠ·ΠΈΡΡΠ΅Ρ ΠΎΠ± ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ ΡΡΠ»ΠΎΠ²Π½ΠΎΠΉ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ. ΠΡΠ»ΠΈ ΡΡΠ½ΠΊΡΠΈΡ thread_function() Π±ΡΠ»Π° Π·Π°Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°Π½Π° Π² ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠΈ ΡΠΈΠ³Π½Π°Π»Π°, ΠΎΠ½Π° ΡΠ°Π·Π±Π»ΠΎΠΊΠΈΡΡΠ΅ΡΡΡ ΠΈ ΡΠ½ΠΎΠ²Π° ΠΏΡΠΎΠ²Π΅ΡΡΠ΅Ρ ΡΠ»Π°Π³.
ΠΠΎ ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ ΠΎΠ΄Π½Π° ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ°: Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ Π³ΠΎΠ½ΠΊΠ° ΠΌΠ΅ΠΆΠ΄Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠ΅ΠΉ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ ΡΠ»Π°Π³Π° ΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠ΅ΠΉ ΡΠΈΠ³Π½Π°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΈΠ»ΠΈ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΡ ΡΠΈΠ³Π½Π°Π»Π°. ΠΡΠ΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, ΡΡΠΎ ΡΡΠ½ΠΊΡΠΈΡ thread_function() ΠΏΡΠΎΠ²Π΅ΡΡΠ΅Ρ ΡΠ»Π°Π³ ΠΈ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΠ²Π°Π΅Ρ, ΡΡΠΎ ΠΎΠ½ Π½Π΅ ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½. Π ΡΡΠΎΡ ΠΌΠΎΠΌΠ΅Π½Ρ ΠΏΠ»Π°Π½ΠΈΡΠΎΠ²ΡΠΈΠΊ Linux ΠΏΡΠ΅ΡΡΠ²Π°Π΅Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ° ΠΈ Π°ΠΊΡΠΈΠ²ΠΈΠ·ΠΈΡΡΠ΅Ρ Π³Π»Π°Π²Π½ΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ. ΠΠΎ ΡΡΠ΅ΡΠ΅Π½ΠΈΡ ΠΎΠ±ΡΡΠΎΡΡΠ΅Π»ΡΡΡΠ² ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° ΠΊΠ°ΠΊ ΡΠ°Π· Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ Π² ΡΡΠ½ΠΊΡΠΈΠΈ set_thread_flag(). ΠΠ½Π° ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅Ρ ΡΠ»Π°Π³ ΠΈ ΡΠΈΠ³Π½Π°Π»ΠΈΠ·ΠΈΡΡΠ΅Ρ ΠΎΠ± ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ ΡΡΠ»ΠΎΠ²Π½ΠΎΠΉ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ. ΠΠΎ ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ Π² Π΄Π°Π½Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ Π½Π΅Ρ ΠΏΠΎΡΠΎΠΊΠ°, ΠΎΠΆΠΈΠ΄Π°ΡΡΠ΅Π³ΠΎ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΡΡΠΎΠ³ΠΎ ΡΠΈΠ³Π½Π°Π»Π° (Π²ΡΠΏΠΎΠΌΠ½ΠΈΡΠ΅, ΡΡΠΎ ΡΡΠ½ΠΊΡΠΈΡ thread_function() Π±ΡΠ»Π° ΠΏΡΠ΅ΡΠ²Π°Π½Π° ΠΏΠ΅ΡΠ΅Π΄ ΡΠ΅ΠΌ, ΠΊΠ°ΠΊ ΠΏΠ΅ΡΠ΅ΠΉΡΠΈ Π² ΡΠ΅ΠΆΠΈΠΌ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΡ), ΡΠΈΠ³Π½Π°Π» ΠΎΠΊΠ°ΠΆΠ΅ΡΡΡ ΠΏΠΎΡΠ΅ΡΡΠ½. ΠΠΎΠ³Π΄Π° Linux Π²Π½ΠΎΠ²Ρ Π°ΠΊΡΠΈΠ²ΠΈΠ·ΠΈΡΡΠ΅Ρ Π΄ΠΎΡΠ΅ΡΠ½ΠΈΠΉ ΠΏΠΎΡΠΎΠΊ, ΠΎΠ½ Π½Π°ΡΠ½Π΅Ρ ΠΆΠ΄Π°ΡΡ ΡΠΈΠ³Π½Π°Π», ΠΊΠΎΡΠΎΡΡΠΉ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π½ΠΈΠΊΠΎΠ³Π΄Π° Π±ΠΎΠ»ΡΡΠ΅ Π½Π΅ ΠΏΡΠΈΠ΄Π΅Ρ.
Π§ΡΠΎΠ±Ρ ΠΈΠ·Π±Π΅ΠΆΠ°ΡΡ ΡΡΠΎΠΉ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ, Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΎΠ΄Π½ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎ Π·Π°Ρ Π²Π°ΡΠΈΡΡ ΠΈ ΡΠ»Π°Π³, ΠΈ ΡΠΈΠ³Π½Π°Π»ΡΠ½ΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΈΡΠΊΠ»ΡΡΠ°ΡΡΠ΅Π³ΠΎ ΡΠ΅ΠΌΠ°ΡΠΎΡΠ°. Π ΡΡΠ°ΡΡΡΡ, Π² Linux ΡΡΠΎ ΠΏΡΠ΅Π΄ΡΡΠΌΠΎΡΡΠ΅Π½ΠΎ. ΠΡΠ±Π°Ρ ΡΠΈΠ³Π½Π°Π»ΡΠ½Π°Ρ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ Π΄ΠΎΠ»ΠΆΠ½Π° ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ ΡΠΎΠ²ΠΌΠ΅ΡΡΠ½ΠΎ Ρ ΠΈΡΠΊΠ»ΡΡΠ°ΡΡΠΈΠΌ ΡΠ΅ΠΌΠ°ΡΠΎΡΠΎΠΌ Π΄Π»Ρ ΠΏΡΠ΅Π΄ΠΎΡΠ²ΡΠ°ΡΠ΅Π½ΠΈΡ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ Π³ΠΎΠ½ΠΊΠΈ. ΠΠ°ΡΠ° ΠΏΠΎΡΠΎΠΊΠΎΠ²Π°Ρ ΡΡΠ½ΠΊΡΠΈΡ Π΄ΠΎΠ»ΠΆΠ½Π° ΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΡ ΡΠ°ΠΊΠΎΠΌΡ Π°Π»Π³ΠΎΡΠΈΡΠΌΡ: