C Academy · Урок

Синхронизация и состояния гонки

Реализуйте мьютексы и семафоры для безопасного управления общими ресурсами

Урок 3 из 310 шагов

«Синхронизация и состояния гонки» — бесплатный урок C Academy на CoddyKit. Это урок 3 из 3. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C Academy содержит 3 уроков всего.

Синхронизация и состояния гонки

Когда несколько потоков обращаются к общим ресурсам, могут возникать состояния гонки, приводящие к непредсказуемым результатам.

В этом уроке Вы узнаете:

  • Что такое состояния гонки и как они возникают.
  • Как использовать мьютексы для предотвращения состояний гонки.
  • Как семафоры помогают управлять общими ресурсами.
Синхронизация и состояния гонки — иллюстрация 1

Что такое состояние гонки

Состояние гонки возникает, когда несколько потоков одновременно обращаются к общим данным, что приводит к непредсказуемому поведению.

Пример:

  • Два потока пытаются обновить глобальный счётчик.
  • Итоговое значение может оказаться неверным из-за взаимного вмешательства.

Пример: состояние гонки в многопоточности

Эта программа демонстрирует состояние гонки, при котором несколько потоков изменяют общую переменную.

#include <stdio.h>
#include <pthread.h>

int counter = 0;

void *incrementCounter(void *arg) {
    for (int i = 0; i < 1000000; i++) {
        counter++;
    }
    return NULL;
}

int main() {
    pthread_t t1, t2;
    pthread_create(&t1, NULL, incrementCounter, NULL);
    pthread_create(&t2, NULL, incrementCounter, NULL);
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    printf("Final counter value: %d\n", counter);
    return 0;
}

Предотвращение состояний гонки с помощью мьютекса

Мьютекс (взаимное исключение) гарантирует, что одновременно ресурс доступен только одному потоку.

Функции работы с мьютексом:

  • pthread_mutex_init() — инициализирует мьютекс.
  • pthread_mutex_lock() — блокирует мьютекс.
  • pthread_mutex_unlock() — разблокирует мьютекс.
  • pthread_mutex_destroy() — уничтожает мьютекс.

Пример: использование мьютекса для предотвращения состояний гонки

Эта программа устраняет состояние гонки, используя мьютекс для управления доступом к общему счётчику.

#include <stdio.h>
#include <pthread.h>

int counter = 0;
pthread_mutex_t lock;

void *incrementCounter(void *arg) {
    for (int i = 0; i < 1000000; i++) {
        pthread_mutex_lock(&lock);
        counter++;
        pthread_mutex_unlock(&lock);
    }
    return NULL;
}

int main() {
    pthread_t t1, t2;
    pthread_mutex_init(&lock, NULL);
    pthread_create(&t1, NULL, incrementCounter, NULL);
    pthread_create(&t2, NULL, incrementCounter, NULL);
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    pthread_mutex_destroy(&lock);
    printf("Final counter value: %d\n", counter);
    return 0;
}

Что такое семафор

Семафор — это счётчик, используемый для управления доступом к ресурсам.

Основные функции:

  • sem_init() — инициализирует семафор.
  • sem_wait() — уменьшает значение семафора.
  • sem_post() — увеличивает значение семафора.
  • sem_destroy() — уничтожает семафор.

Пример: использование семафоров для синхронизации

Эта программа использует семафор для управления доступом к общему ресурсу.

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>

sem_t sem;

void *task(void *arg) {
    sem_wait(&sem);
    printf("Thread %d is executing\n", *(int *)arg);
    sem_post(&sem);
    return NULL;
}

int main() {
    pthread_t t1, t2;
    int id1 = 1, id2 = 2;
    sem_init(&sem, 0, 1);
    pthread_create(&t1, NULL, task, &id1);
    pthread_create(&t2, NULL, task, &id2);
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    sem_destroy(&sem);
    return 0;
}

Рекомендации по синхронизации потоков

Чтобы избежать состояний гонки:

  • Используйте мьютексы для защиты общих переменных.
  • Используйте семафоры для управления ресурсами.
  • По возможности сокращайте использование общих ресурсов.

Итоги

В этом уроке Вы узнали:

  • Что такое состояния гонки и как они возникают.
  • Как использовать мьютексы для предотвращения состояний гонки.
  • Как семафоры помогают управлять доступом к общим ресурсам.

На этом завершается раздел «Многопоточность и параллелизм в C»!

Синхронизация и состояния гонки — иллюстрация 10
Можно начать бесплатно

Изучай C с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
39
Уроки
144

Часто задаваемые вопросы

Урок «Синхронизация и состояния гонки» бесплатный?

Да — полный текст урока «Синхронизация и состояния гонки» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C Academy, подпишись на CoddyKit PRO. Курс C Academy содержит 3 уроков всего.

Чему я научусь в уроке «Синхронизация и состояния гонки»?

Реализуйте мьютексы и семафоры для безопасного управления общими ресурсами Ты практикуешь C Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C Academy?

Предыдущий опыт не требуется. C Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 3.

Сколько времени занимает урок «Синхронизация и состояния гонки»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C Academy?

Да. Каждый урок C Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Знакомство с потоками
  2. Создание и управление потоками
  3. Синхронизация и состояния гонки
← Назад к C Academy