#c #multithreading
Вопрос:
Вот пример кода:
#include <iostream>
#include <thread>
#include <mutex>
int value = 0;
void criticalSection(int changeValue)
{
std::mutex mtx;
std::unique_lock<std::mutex> uniqueLock(mtx);
value = changeValue;
std::cout << value << std::endl;
uniqueLock.unlock();
uniqueLock.lock();
value;
std::cout << value << std::endl;
}
int main(int argc, char **argv)
{
std::thread t1(criticalSection, 1), t2(criticalSection, 2);
t1.join();
t2.join();
return 0;
}
Мой вопрос: какова область применения mtx в приведенном выше коде? Будет ли каждый поток создавать mtx в этом потоке? Есть ли какая-то разница, если я укажу mtx в качестве глобальной переменной вместо локальной переменной?
Я только начал изучать многопоточность на C . Большое вам спасибо за вашу помощь.
Комментарии:
1. Наличие функции
void foo () {int bar = 0; }
, какова область действияbar
переменной и будет ли создаваться новаяbar
переменная при каждом вызовеfoo
функции? Ответ тот же, что и уstd::mutex
меня .2.Область действия a
std::mutex
такая же, как и для любого другого объекта. «Будет ли каждый поток создавать mtx в этом потоке?«- Да, если ты не сделаешь этоstatic
примером3. Это та же область, что и если
int a;
бы была объявлена вместо нее.4. Правило простое: область действия мьютекса должна соответствовать области действия защищаемых данных.
5. Большое вам всем спасибо. Это мой первый вопрос, и я получил так много полезных ответов. Я надеюсь, что у вас у всех будет хороший день!
Ответ №1:
Для мьютексов не существует специальных правил определения области действия. Их область применения заканчивается на следующем }
. В вашем коде каждый вызов criticalSection
создает новый mutex
экземпляр. Следовательно, мьютекс невозможно использовать для синхронизации двух потоков. Для этого обоим потокам потребуется использовать один и тот же мьютекс.
Вы можете передать ссылку на мьютекс функции:
#include <iostream>
#include <thread>
#include <mutex>
int value = 0;
void criticalSection(int changeValue,std::mutexamp; mtx)
{
std::unique_lock<std::mutex> uniqueLock(mtx);
//...
}
int main(int argc, char **argv)
{
std::mutex mtx;
std::thread t1(criticalSection, 1,std::ref(mtx)), t2(criticalSection, 2,std::ref(mtx));
t1.join();
t2.join();
return 0;
}
В качестве альтернативы вы можете использовать a std::atomic<int> value;
и удалить мьютекс, когда value
это единственное общее состояние.
Комментарии:
1. Спасибо. После прочтения вашего ответа мой вопрос решен. Хорошего дня!
Ответ №2:
mutex
Тип не изменяет правила C в отношении того, как работают переменные и объекты.
Если вы объявите static
непеременную в стеке, каждый вызов этой функции создаст свою собственную версию этой переменной. Независимо от того, о какой теме идет речь. Все это отдельные и отличные друг от друга объекты.
Когда вы блокируете a mutex
, вы блокируете этот объект. Другие объекты того же типа не связаны с этой блокировкой.
Чтобы сделать mutex
что-то полезное, обе части кода, пытающиеся заблокировать его, должны блокировать один и тот же объект. То, как вы это сделаете, в конечном счете зависит от ваших потребностей.
Комментарии:
1. Ну, это немного волшебно, просто никак не связано с областью применения
2. Большое вам спасибо за вашу помощь. Теперь я знаю, что мне нужно сделать объект мьютекса статичным.