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

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

Восстановить пароль Регистрация
 
karat39
4 / 4 / 1
Регистрация: 09.02.2016
Сообщений: 74
24.10.2016, 17:48     Причины последовательной работы потоков? #1
имею 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++ Linux
C++ Builder Создание потоков для работы со строками
Сравнение рекурсивного параллелизма и последовательной рекурсивной программы для реализации алгоритма быстрой C++
Метод последовательной верхней релаксации Visual C++
C++ Найти причины и способы исправления ошибки
Найти причины и способы устранения ошибки C++
Найти причины и способы исправления ошибок в коде C++
C++ Найти причины ошибочной работы пользовательского класса MyVector

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,915
Записей в блоге: 2
Завершенные тесты: 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
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,915
Записей в блоге: 2
Завершенные тесты: 1
24.10.2016, 23:03     Причины последовательной работы потоков? #4
Цитата Сообщение от karat39 Посмотреть сообщение
заработало.
Если уберете unlock, то оно также будет последовательно работать.
karat39
4 / 4 / 1
Регистрация: 09.02.2016
Сообщений: 74
24.10.2016, 23:10  [ТС]     Причины последовательной работы потоков? #5
Я понял, что меня ввело в заблуждение. В том материале, который я изучаю, говорится, что во время wait мьютекс освобождается. И ни слова, что по выходу захватывается, а я и не додумался. =)
Yandex
Объявления
24.10.2016, 23:10     Причины последовательной работы потоков?
Ответ Создать тему
Опции темы

Текущее время: 17:35. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru