6 / 6 / 2
Регистрация: 09.02.2016
Сообщений: 138
1

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

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

Author24 — интернет-сервис помощи студентам
имею 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, то потоки действительно принтуют в разнобой, то есть работают параллельно.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
24.10.2016, 17:48
Ответы с готовыми решениями:

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

Область видимости общей переменной для потоков + закрытие потоков
Есть два вопроса про потоки. Первый. Как можно сделать общую переменную для основного потока и...

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

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

4
Неэпический
17869 / 10634 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 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++;
        }
    }
}
1
6 / 6 / 2
Регистрация: 09.02.2016
Сообщений: 138
24.10.2016, 22:59  [ТС] 3
Цитата Сообщение от Croessmah Посмотреть сообщение
/Перенес сюда.
спасибо, сейчас попробую

Добавлено через 11 минут
Цитата Сообщение от Croessmah Посмотреть сообщение
Перенес сюда. Вам нужен общий mutex, а не общий unique_lock
спасибо, действительно так и есть, заработало.
0
Неэпический
17869 / 10634 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
24.10.2016, 23:03 4
Цитата Сообщение от karat39 Посмотреть сообщение
заработало.
Если уберете unlock, то оно также будет последовательно работать.
1
6 / 6 / 2
Регистрация: 09.02.2016
Сообщений: 138
24.10.2016, 23:10  [ТС] 5
Я понял, что меня ввело в заблуждение. В том материале, который я изучаю, говорится, что во время wait мьютекс освобождается. И ни слова, что по выходу захватывается, а я и не додумался. =)
0
24.10.2016, 23:10
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.10.2016, 23:10
Помогаю со студенческими работами здесь

Создание и завершение процессов и потоков. Приоритеты выполнения потоков
Здравствуйте. Буду очень раз если поможете понять,что конкретно нужно сделать в вот этом...

Замедление работы потоков если запущено несколько потоков
Есть отдельный поток который движет красным квадратом. Он каждую миллисекунду меняет положение...

$.cookie причины НЕ работы скрипта
Добрый день! Подключены библиотеки jquery и jquery.cookie.js. Вот мой скрипт: ...

Несанкционированное замедление работы потоков
Здравствуйте! Имеется программа, моделирующая движение некоторых объектов по прямоугольной...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru