Форум программистов, компьютерный форум CyberForum.ru

C++

Войти
Регистрация
Восстановить пароль
 
karat39
4 / 4 / 1
Регистрация: 09.02.2016
Сообщений: 74
#1

Причины последовательной работы потоков? - C++

24.10.2016, 17:48. Просмотров 244. Ответов 4
Метки нет (Все метки)

имею gcc 4.8
Следующий код:

Имею такие глобальные переменные

C++
1
2
3
4
5
6
7
int                             thread_started_count = 0;   // счетчик-барьер кол-ва потоков
std::thread                     thread_1;                   // поток 1
std::thread                     thread_2;                   // поток 2
std::mutex                      thread_count_busy;          // мьютекс для счетчика
std::mutex                      search_busy;                // мьютекс, только для condition_variable
std::unique_lock<std::mutex>    lck(search_busy);           
std::condition_variable         start_search;               // condition_variable для оповещения, что можно стартовать потокам
Имею две однотипные функции для двух потоков.
Первая
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void    thread_work_1 () {
    thread_count_busy.lock();
    thread_started_count++;
    thread_count_busy.unlock(); 
    
    while (true) {
        printf ("\n now waiting 1...\n");
        start_search.wait(lck);
        printf ("\n starting 1...\n");
        int n = 0;
        while (n < 100) {
            printf (" 1");  
            n++;
        }
    }
}
Вторая
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void    thread_work_2 () {
    thread_count_busy.lock();
    thread_started_count++;
    thread_count_busy.unlock();
    
    while (true) {
        printf ("\n now waiting 2...\n");
        start_search.wait(lck);
        printf ("\n starting 2...\n");
        int n = 0;
        while (n < 100) {
            printf (" 2");
            n++;
        }
    }
}
Основная программа
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int main () {
 
    printf ("program started\n");
    
    thread_1 = std::thread (thread_work_1);
    thread_2 = std::thread (thread_work_2);
    
    thread_1.detach();  
    thread_2.detach();
    while (thread_started_count != 2) {usleep (1);}
 
    start_search.notify_all();
 
    int n = 0;
    while (true) {
        if (n == 500) {
            start_search.notify_all();
            n = 0;
        }
        n++;
    }
}
Логика очень простая.
1) Создаю два потока и запускаю их в фон.
2) Потоки запускаются и переходят в спящий режим
3) Когда счетчик запущенных потоков =2, то пробуждаем потоки, они начинают работать.
4) Потоки просто выводят на экран 100 цифр. И заново засыпают.
5) В основном потоке (программе) при счетчике n = 500, потоки опять будятся. И так все зацикленно.

Внимание. Вопрос.
Получаю некий результат
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
program started
 
 now waiting 1...
 
 now waiting 2...
 
 starting 1...
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 now waiting 1...
 
 starting 2...
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 now waiting 2...
 
 starting 1...
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 now waiting 1...
 
 starting 2...
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 now waiting 2...
Как видим, потоки работают по очереди. Не пойму почему так. Где закралась ошибка? Прошу помощь зала.
Если избавляюсь в коде от condition_variable, то потоки действительно принтуют в разнобой, то есть работают параллельно.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.10.2016, 17:48
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Причины последовательной работы потоков? (C++):

Создание потоков для работы со строками - C++ Builder
Мне нужно много поточное приложение которое может отрыть текстовый файл и в разных потоках работать с этими строками но в каждом потоке...

Найти причины и способы исправления ошибок в коде - C++ Builder
//--------------------------------------------------------------------------- #include &lt;vcl.h&gt; #include &quot;math.h&quot; #pragma hdrstop ...

Найти причины и способы исправления ошибок в коде (C++ Builder6) - C++ Builder
помогите найти ошибку //--------------------------------------------------------------------------- #include &lt;vcl.h&gt; ...

Каковы могут быть причины возникновения ошибки данного рода? - C++ Builder
Ошибка возникает при попытке записать переменную типа byte в буфер памяти устройства Advantech usb-4751. Мои предположения -...

Найти причины возникновения ошибки E2451 Undefined symbol 'tank_r' - C++ Builder
Решил написать игрулю, о танках и наткнулся на проблему с поворотами. нашел ответ и немного переписал код. выдает ошибку: Unit1.cpp(68):...

Найти причины и способы исправления ошибки W8060: Possibly incorrect assignment - C++ Builder
Здравствуйте. При открытие файла выскакивает пот эта ошибка Unit1.cpp(100): W8060 Possibly incorrect assignment и показывает вот на...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Croessmah
Модератор
Эксперт CЭксперт С++
13154 / 7417 / 831
Регистрация: 27.09.2012
Сообщений: 18,254
Записей в блоге: 3
Завершенные тесты: 1
24.10.2016, 22:46 #2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
void    thread_work_1 () {
    thread_count_busy.lock();
    thread_started_count++;
    thread_count_busy.unlock(); 
    
    while (true) {
        std::unique_lock<std::mutex> lck(search_busy);//Перенес сюда. Вам нужен общий mutex, а не общий unique_lock
        printf ("\n now waiting 1...\n");
        start_search.wait(lck);//После выхода из ожидания mutex будет захвачен.
        printf ("\n starting 1...\n");
        lck.unlock();//Убираем блокировку мьютекса
        int n = 0;
        while (n < 100) {
            printf (" 1");  
            n++;
        }
    }
}
 
 
void    thread_work_2 () {
    thread_count_busy.lock();
    thread_started_count++;
    thread_count_busy.unlock();
    
    while (true) {
        std::unique_lock<std::mutex> lck(search_busy);//Перенес сюда. Вам нужен общий mutex, а не общий unique_lock
        printf ("\n now waiting 2...\n");
        start_search.wait(lck);//После выхода из ожидания mutex будет захвачен.
        printf ("\n starting 2...\n");
        lck.unlock();//Убираем блокировку мьютекса
        int n = 0;
        while (n < 100) {
            printf (" 2");
            n++;
        }
    }
}
karat39
4 / 4 / 1
Регистрация: 09.02.2016
Сообщений: 74
24.10.2016, 22:59  [ТС] #3
Цитата Сообщение от Croessmah Посмотреть сообщение
/Перенес сюда.
спасибо, сейчас попробую

Добавлено через 11 минут
Цитата Сообщение от Croessmah Посмотреть сообщение
Перенес сюда. Вам нужен общий mutex, а не общий unique_lock
спасибо, действительно так и есть, заработало.
Croessmah
Модератор
Эксперт CЭксперт С++
13154 / 7417 / 831
Регистрация: 27.09.2012
Сообщений: 18,254
Записей в блоге: 3
Завершенные тесты: 1
24.10.2016, 23:03 #4
Цитата Сообщение от karat39 Посмотреть сообщение
заработало.
Если уберете unlock, то оно также будет последовательно работать.
karat39
4 / 4 / 1
Регистрация: 09.02.2016
Сообщений: 74
24.10.2016, 23:10  [ТС] #5
Я понял, что меня ввело в заблуждение. В том материале, который я изучаю, говорится, что во время wait мьютекс освобождается. И ни слова, что по выходу захватывается, а я и не додумался. =)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.10.2016, 23:10
Привет! Вот еще темы с ответами:

Метод последовательной верхней релаксации - Visual C++
Решить методом последовательной верхней релаксации СЛАУ с разреженной матрицей 50х50. Коэффициент релаксации подобрать. Помогите мне....

Область видимости общей переменной для потоков + закрытие потоков - C++ WinAPI
Есть два вопроса про потоки. Первый. Как можно сделать общую переменную для основного потока и моих ? struct ThreadInfo1 { int...

Найти причины ошибочной работы пользовательского класса MyVector - C++
Подскажите, что у меня не так с массивами. Почему вылет программы идет после несколько запусков консоли? Что я сделал не так? #include...

Вывод результатов работы потоков разными цветами - C++
Реализую параллельную сортировку методом Шелла. При этом нужно показать, какие перестановки какой из потоков выполнил, разукрасив строки...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
24.10.2016, 23:10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru