в чем особенности блокировок , то есть в чем отличие блокировок в случае буфиризированного канала с буфером в 1 и мьютекса. также приведи наглядный пример
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
int counter = 0;
void incrementCounter() {
mtx.lock();
counter++;
mtx.unlock();
}
int main() {
std::thread t1(incrementCounter);
std::thread t2(incrementCounter);
t1.join();
t2.join();
std::cout << "Counter value: " << counter << std::endl;
return 0;
}
В данном примере мы создаем два потока, которые вызывают функцию "incrementCounter". Внутри этой функции мы блокируем мьютекс, увеличиваем значение счетчика на единицу и разблокируем мьютекс. Таким образом, только один поток может иметь доступ к увеличению счетчика в определенный момент времени, что исключает возможность возникновения проблемы гонки. После завершения работы потоков выводим значение счетчика на экран.
Еще одним примером блокировок является буферизированный канал с буфером в 1. В отличие от мьютекса, буферизированный канал позволяет временно хранить данные, которые могут быть получены или отправлены потоками исполнения. Буферизированный канал с буфером в 1 имеет особенность - он блокирует поток только в том случае, если буфер полностью заполнен. В противном случае, когда буфер не заполнен, поток исполнения может сразу отправить данные в канал или получить данные из него, не блокируясь.
Например, рассмотрим ситуацию, когда один поток отправляет данные в буферизированный канал, а другой поток получает данные. По умолчанию, буферизированный канал предоставляет блокирующую операцию чтения, то есть поток получения будет блокироваться до тех пор, пока не будут доступны новые данные в канале. Однако, если мы используем буферизированный канал с буфером в 1, то блокировка будет происходить только тогда, когда буфер полностью заполнен.
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
std::mutex mtx;
std::condition_variable cv;
std::queue<int> buffer;
void senderThread() {
while (true) {
std::this_thread::sleep_for(std::chrono::seconds(1));
std::unique_lock<std::mutex> lock(mtx);
buffer.push(1);
lock.unlock();
cv.notify_one();
}
}
void receiverThread() {
while (true) {
std::this_thread::sleep_for(std::chrono::seconds(1));
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, []{ return !buffer.empty(); });
int data = buffer.front();
buffer.pop();
lock.unlock();
std::cout << "Received data: " << data << std::endl;
}
}
int main() {
std::thread t1(senderThread);
std::thread t2(receiverThread);
t1.join();
t2.join();
return 0;
}
В данном примере мы создаем два потока - отправитель (senderThread) и получатель (receiverThread). Отправитель отправляет данные в буферизированный канал каждую секунду, а получатель получает данные из канала также каждую секунду. При запуске программы можно заметить, что получатель блокируется до тех пор, пока отправитель не добавит данные в канал. Когда буфер полностью заполнен, отправитель будет блокироваться до тех пор, пока получатель не получит данные из канала, освобождая место в буфере.
Таким образом, основные отличия блокировок в случае буферизированного канала с буфером в 1 и мьютекса заключаются в том, что мьютекс блокирует поток до освобождения ресурса, а буферизированный канал с буфером в 1 блокирует поток только при полном заполнении буфера. Эти различия позволяют более эффективно управлять доступом к общим ресурсам в зависимости от конкретной задачи и внешних условий.Нажимая «Регистрация» или «Войти через Google», вы соглашаетесь с Публичной офертой, даете Согласие на обработку персональных данных, а также подтверждаете что вам есть 18 лет
Нажимая «Регистрация» или «Войти через Google», вы соглашаетесь с Публичной офертой, даете Согласие на обработку персональных данных, а также подтверждаете что вам есть 18 лет