2015-07-07 4 views
0

У меня есть простая программа, в которой я хочу выводить числа 1-100, причем один поток выводит все нечетные числа, а другой - все четные числа. Используя lock_guard, это довольно простая задача. Код следующим образом:использовать переменную условия вместо lock_guard

#include <iostream> 
#include <mutex> 
#include <condition_variable> 
#include <thread> 

std::mutex m; 


void print_numbers(int i) 
{ 
    for (i; i <= 100; i++) 
    { 
     std::lock_guard<std::mutex> locker(m); 
     std::cout << i << std::endl; 
     ++i; 
    } 
} 

int main() 
{ 
    std::thread t1(print_numbers, 0); 
    std::thread t2(print_numbers, 1); 
    t1.join(); 
    t2.join(); 
    return 0; 
} 

Мой вопрос, как я могу использовать переменные условия, чтобы сделать это, и, возможно, сделать его немного более элегантно?

+1

Простые 'std :: mutex' (и' std :: lock_guard' вместе) и 'std :: condition_variable' - это как-то _orthogonal_ понятия. Фактически для 'std :: condition_variable' на самом деле требуется использовать как минимум 2 мьютекса, поэтому можно утверждать, что это более элегантно. Вы используете переменные условия, чтобы пробудить потоки для изменений состояния, таким образом, они похожи на семафоры, я не вижу, как этот код действительно нужен. –

+0

Я понимаю, спасибо. Однако, тем не менее, ради изучения только, предложите ли вы способ использования двух мьютексов с переменной условия для достижения того же результата? – Iason

+0

Ну, вам даже не нужен 'std :: mutex' для вашего образца кода, 2 потока работают полностью независимо от копии' i', изменения никогда не будут мешать или будут подвержены условиям гонки. Ваш 'std: mutex m;' является фиктивным и не нужен. –

ответ

0

В коде отсутствует обмен. Каждый поток имеет локальную переменную i. Условие POSIX используется для межпоточной связи/сигнализации. Идея проста:

  1. нить проверить булевы предикаты (в зависимости от общего состояния) и решили «ждать», когда предикат является ложным (pthread_cond_wait в POSIX)

  2. другой поток может изменить общее состояние и, следовательно, влияют на значение булевого предиката. Если этот поток изменяет состояние, он может уведомить другой поток (Thread # 1) о том, что он должен проснуться и перепроверить свой предикат, значение которого теперь может измениться (pthread_cond_signal и pthread_cond_broadcast в POSIX).

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

Типичным вариантом использования условия POSIX является общая очередь. Потребитель хочет «потреблять» элементы данных из очереди и, чтобы сделать это, должен ждать булевского предиката [очередь не пуста]. Производитель генерирует элементы данных, которые он откладывает в общей очереди. Поскольку он добавляет элементы, он должен уведомить всех «официантов», которые они должны перепроверять.

Итог: Условия здесь не помогают. Вам даже не нужны мьютексы в вашем примере. И условия должны использоваться с мьютексом в любом случае (вызов pthread_cond_wait принимает в качестве входного адреса мьютекса для атомарного освобождения блокировки и сна при условии). mutex для взаимное исключение. Условия означают для сигнализация. Две совершенно разные цели.

+0

Исправьте меня, если я ошибаюсь, конечно, Лоран Мишель, @ πάνταῥεῖ. Меня это совсем не волнует. Общий ресурс между потоками здесь - cout. Если я НЕ использую мьютекс здесь, я получаю фиктивный вывод, все четные числа сначала и все нечетные после. Чтобы последовательно печатать все числа, мне действительно нужен мьютекс. – Iason

+0

Ваш код * предлагает * вы заботитесь о 'i', потому что вы увеличиваете' i' внутри lock_guard. Только делайте то, что вы абсолютно должны в замке. – kfsone

+0

@lason: мое предположение заключается в том, что cout предназначен для отладки. Да, печать должна быть синхронизирована, но это также взаимное исключение. Это не меняет характера реакции: условия не предназначены для решения взаимных исключений. Они предназначены для помощи в сигнализации. –

 Смежные вопросы

  • Нет связанных вопросов^_^