Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484

Можно ли сделать доступным для всех классов пул потоков?

21.01.2021, 18:57. Показов 2032. Ответов 21
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
У меня есть пул потоков который я хочу сделать доступным для всех чтолибоделающих классов.
Есть класс основной Base и два класса которые наследуют этот класс.
могу ли я спокойно сделать вот так :
в Base.cpp ThreadPool tPool;
в Base.hpp extern ThreadPool tPool;
в inhert1.hpp #include "Base.hpp"
в inhert2.hpp #include "Base.hpp"
и далее в каком-то worker
#include inhert1.hpp
#include inhert2.hpp
?
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
21.01.2021, 18:57
Ответы с готовыми решениями:

Реализовать пул потоков, в который можно помещать функцию
не могу реализовать как в книге главу 9 пул потоков который,в который можно помещать функцию что бы она возвращала значение вот код который...

Один раз заполнить массив и сделать его доступным для всех модулей
Всем привет. У меня есть книга с макросами, где часто приходится обращаться к базам данных, которые в другой книге. Есть идея скопировать...

Сделать функцию видимой для всех классов проекта
Добрый день! Знаю, что банальный вопрос, но хочу писать код красиво! Есть программа и есть множество функций, которые должны...

21
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13184 / 6820 / 1821
Регистрация: 18.10.2014
Сообщений: 17,260
21.01.2021, 19:29
Вы спрашиваете, как сделать пул потоков глобальной переменной? Так же как и любую другую переменную делают глобальной переменной.

Можно так как вы написали. (Однако при чем здесь какие-то inhert1.hpp и inhert2.hpp - не ясно.)

А можно просто

C++
1
inline ThreadPool tPool;
в каком-то общем заголовочном файле и все.
0
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
21.01.2021, 19:49  [ТС]
TheCalligrapher, сделал так как Вы написали, выбрасывается exception из пула , вот код(.cpp файлы не буду кидать тк не используются) :

main.cpp
C++
1
2
3
4
5
6
7
8
9
10
#include "worker/worker.hpp"
 
void test(){
}
 
int main(){
    worker work;
    work.startwork();
    return 0;
}
worker.hpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "inher1/inher1.hpp"
#include "inher2/inher2.hpp"
 
class worker
{
private:
    inher1 in1;
    inher2 in2;
public:
    in1():
    in2("GL45PMS3JFOXZ2RP")
    {}
 
    void startwork();
};
worker.cpp
C++
1
void worker::startwork(){}
inher1.hpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <string>
#include "Base/Base.hpp"
 
class inher1 : public Base
{
private:
    std::string parseSmth(std::vector<type>&  ,std::string);
 
    static uint64_t writeData(char *, uint64_t , uint64_t , std::string*);
public:
 
    void getSmth(std::vector<type>& slots,uint16_t ,uint16_t);
};
inher2.hpp
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
39
40
41
42
#include "Base/Base.hpp"
#include <fstream>
#include <map>
 
class inher2 : public Base
{
private:
    std::mutex mSlotsMutex;
    std::mutex dataFileMutex;
    std::mutex syncMutex;
 
    std::atomic<uint32_t> parsingCounter;
 
    const std::string apiKey;
 
    std::ofstream ofGood;
    std::ofstream ofBad;
 
    std::map<std::string,type> slotsMap;
 
    void parseSmth(const std::string, type&);
    void getSmth(const item&);
    void showProgressBar(const uint32_t);
 
    void enableSales();
 
    CURLcode performReq(CURL * _curlHandle);
 
    static uint64_t writeData(char *, uint64_t , uint64_t , std::string*);
    static uint64_t writeEmptyData(char *, uint64_t , uint64_t , std::string*);
public:
    inher2(std::string _apiKey):
    parsingCounter(0),
    apiKey(_apiKey),
    ofGood("dataGood.txt", std::ios::app),
    ofBad("dataBad.txt", std::ios::app)
    {};
 
    ~marketapi(){ofGood.close(); ofBad.close();}
 
    void checkDealsList();
};
Base.hpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
inline ThreadPool tPool{};
 
class Base
{
protected:
 
    CURL *curlHandle;
 
    void resetOpts();
    std::string textToUrlEncoded(const std::string&);
public:
    trader():
    curlHandle(curl_easy_init())
    {}
 
    ~trader(){curl_easy_cleanup(curlHandle); tPool.StopPool();}
};
ну и код который бросает исключения:

tpool.hpp
Кликните здесь для просмотра всего текста
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
ThreadPool::ThreadPool() :nthreads(1),stop(false) {
 
    for (unsigned int i = 0; i < nthreads; ++i) {
 
        threads.emplace_back( //add thread to threads container
            std::thread( //thread creation
 
                [this]() { //lambda for wating for tasks
 
                    while (!stop) {
                        task_wrapper task; //create it before mutex lock 
 
                        {
                            std::unique_lock<std::mutex> ul(mtx); //unique_lock is used for condition var
 
                            cv.wait(ul, [this]() { //wait for tasks or stop of the programm
 
                                return !tasks.empty() || stop;
 
                                });
 
                            if (stop)
                                return;
 
                            task = std::move(tasks.front()); //take task from tasks container
 
                            tasks.pop(); //delete taken task from container
 
                        }
 
                        task(); //run task
 
                    }
 
                }));
 
    }
}


Добавлено через 30 секунд
exception
terminate called after throwing an instance of 'std::system_error'
what(): Invalid argument
zsh: abort (core dumped) ./test


Добавлено через 1 минуту
работает странно, если я уберу либо inher1 либо inher2 из конструктора worker то всё окей, но если их двое то плохо, исключение бросатеся в месте threads.emplace_back
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13184 / 6820 / 1821
Регистрация: 18.10.2014
Сообщений: 17,260
21.01.2021, 19:59
Цитата Сообщение от ReYalp Посмотреть сообщение
исключение бросатеся в месте threads.emplace_back
Вы нам постите тут какой-то шлак, не имеющий ничего общего с реальным кодом. Что это за чушь?

C++
1
2
3
4
5
6
7
8
9
class worker
{
private:
    inher1 in1;
    inher2 in2;
public:
    in1():
    in2("GL45PMS3JFOXZ2RP")
    {}
Копаться в этом никакого смысла нет.
0
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
21.01.2021, 20:00  [ТС]
TheCalligrapher, это реальный код в котором я убрал всё лишнее , там должно быть worker():in1(),in2(string) очевидно
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13184 / 6820 / 1821
Регистрация: 18.10.2014
Сообщений: 17,260
21.01.2021, 20:03
Лучший ответ Сообщение было отмечено ReYalp как решение

Решение

Цитата Сообщение от ReYalp Посмотреть сообщение
я убрал всё лишнее
Вот именно. А как вы отличали "лишнее" от "не лишнего"?

Что такое threads из вашего кода не видно. Реализация вашего ThreadPool в любом случае, очевидно, лишней не является. Где она?

И идея делать все это в конструкторе ThreadPool - это за гранью. Сколько раз твердили: никакой серьезной работы никогда в конструкторе не делать! В конструкторе - только базовая инициализация.
0
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
21.01.2021, 20:47  [ТС]
TheCalligrapher, легко, cpp файлы не показывал тк они не используются(конструкторы в hpp), имена некоторых переменных, объектов и тд сменил тк это ЛИШНЕЕ для Вас, и во время изменения одного из имен сделал ошибку как Выше

Добавлено через 1 минуту
TheCalligrapher,
tpool.hpp
Кликните здесь для просмотра всего текста
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#ifndef THREAD_POOL_HPP
#define THREAD_POOL_HPP
//Example of thread pool
 
#include<thread> //for std::thread
#include<condition_variable> //for std::conditional_variable
#include<mutex> //for std::mutex
#include<future> //for std::future
#include<queue> //for std::queue
#include<functional> //for std::bind
#include<atomic> //for std::atomic
#include<type_traits> //for std::invoke_result c++17
#include"taskwrapper.hpp" //for task_wrapper
 
class ThreadPool
{
public:
 
    ThreadPool(); //on default creates 1 thread
    ThreadPool(const size_t); //creates number of threads
    ThreadPool(const ThreadPool&) = delete; //no copy constructor
    ThreadPool(ThreadPool&&) = delete; //no move constructor
 
    ~ThreadPool();
 
    ThreadPool& operator=(const ThreadPool&) = delete; //no copy operator
    ThreadPool& operator=(ThreadPool&&) = delete; //no move operator
 
    void AddThread(const size_t n); //Increase number of threads in the pool
 
    void StopPool(); //Stop poooling
 
    size_t ThreadsNumber();//return the nuber of the working threads
 
 
    template<typename T, typename... Args>  
    std::future<typename std::invoke_result<T,Args...>::type> AddTask(T&& obj, Args&&... args){ //return future which contains function return value
 
        using rtype = typename std::invoke_result<T,Args...>::type; // deduce function return type
 
        std::packaged_task<rtype()> ptask(std::bind(std::forward<T>(obj), std::forward<Args>(args)...));
        std::future<rtype> future = ptask.get_future(); //get future from packaged task
 
        {
            std::lock_guard<std::mutex> lg(mtx); //needed to safely add task to tasks container
 
            tasks.emplace(std::move(ptask)); //add task to task container.
 
        }
 
        cv.notify_one(); //notify waiting thread
 
        return future; //return future
    }
 
 
private:
    size_t nthreads; //number of threads
 
    std::atomic<bool> stop; //variable to check if we have to stop threading
 
    std::mutex mtx;
 
    std::condition_variable cv;
 
    std::queue<task_wrapper> tasks; //container for tasks
 
    std::vector<std::thread> threads; //container for threads
 
};
#endif


tpool.cpp
Кликните здесь для просмотра всего текста
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include "threadpool.hpp"
 
ThreadPool::ThreadPool() :nthreads(1),stop(false) {
 
    for (unsigned int i = 0; i < nthreads; ++i) {
 
        threads.emplace_back( //add thread to threads container
            std::thread( //thread creation
 
                [this]() { //lambda for wating for tasks
 
                    while (!stop) {
                        task_wrapper task; //create it before mutex lock 
 
                        {
                            std::unique_lock<std::mutex> ul(mtx); //unique_lock is used for condition var
 
                            cv.wait(ul, [this]() { //wait for tasks or stop of the programm
 
                                return !tasks.empty() || stop;
 
                                });
 
                            if (stop)
                                return;
 
                            task = std::move(tasks.front()); //take task from tasks container
 
                            tasks.pop(); //delete taken task from container
 
                        }
 
                        task(); //run task
 
                    }
 
                }));
 
    }
}
 
 
ThreadPool::ThreadPool(const size_t n):nthreads(n),stop(false) {
 
    for (unsigned int i = 0; i < nthreads; ++i) {
 
        threads.emplace_back( //add thread to threads container
            std::thread( //thread creation
 
                [this]() { //lambda for wating for tasks
                    while (!stop) {
                        task_wrapper task; //create it before mutex lock 
 
                        {
                            std::unique_lock<std::mutex> ul(mtx); //unique_lock is used for condition var
 
                            cv.wait(ul, [this]() { //wait for tasks or stop of the programm
 
                                return !tasks.empty() || stop;
 
                                });
 
                            if (stop)
                                return;
 
                            task = std::move(tasks.front()); //take task from tasks container
 
                            tasks.pop(); //delete taken task from container
 
                        }
 
                        task(); //run task
 
                    }
                }));
 
    }
 
}
 
 
ThreadPool::~ThreadPool() {
    if(!stop)
        StopPool();
}
 
 
void ThreadPool::StopPool() {
 
    stop = true;
 
    cv.notify_all();
 
    for (auto& thread : threads) {
        thread.join();
    }
 
}
 
 
void ThreadPool::AddThread(const size_t n) {
 
    nthreads += n;
 
    for (unsigned int i = 0; i < n; ++i) {
 
        threads.emplace_back( //add thread to threads container
            std::thread( //thread creation
 
                [this]() { //lambda for wating for tasks
 
                    while (!stop) {
                        task_wrapper task; //create it before mutex lock 
 
                        {
                            std::unique_lock<std::mutex> ul(mtx); //unique_lock is used for condition var
 
                            cv.wait(ul, [this]() { //wait for tasks or stop of the programm
 
                                return !tasks.empty() || stop;
 
                                });
 
                            if (stop)
                                return;
 
                            task = std::move(tasks.front()); //take task from tasks container
 
                            tasks.pop(); //delete taken task from container
 
                        }
 
                        task(); //run task
 
                    }
 
                }));
 
    }
}
 
 
size_t ThreadPool::ThreadsNumber() {
    return nthreads;
}


taskwrapper.hpp
Кликните здесь для просмотра всего текста
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
39
#ifndef TASK_WRAPPER_HPP
#define TASK_WRAPPER_HPP
#include <memory>
 
class task_wrapper{
    public:
        template<typename T>
        task_wrapper(T&& f):func(new impl<T>(std::move(f))){};
 
        task_wrapper() = default;
        task_wrapper(const task_wrapper&) = delete;
        task_wrapper(task_wrapper&& t):func(std::move(t.func)){}
 
        task_wrapper& operator=(const task_wrapper&) = delete;
        task_wrapper& operator=(task_wrapper&& t){
            func = std::move(t.func);
            return *this;
        }
 
        void operator()(){(*func)();}
    private:
        struct impl_base
        {
            virtual void operator()() = 0;
            virtual ~impl_base() = default;
        };
 
        template<typename T>
        struct impl : impl_base
        {
            T f;
            impl(T&& _f):f(std::forward<T>(_f)){}
            virtual void operator()(){f();}
        };
        
        std::unique_ptr<impl_base> func;
        
};
#endif


Добавлено через 2 минуты
TheCalligrapher,
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
И идея делать все это в конструкторе ThreadPool - это за гранью. Сколько раз твердили: никакой серьезной работы никогда в конструкторе не делать! В конструкторе - только базовая инициализация.
Окей, сделаю метод startPool в котором и буду запускать

Добавлено через 6 минут
TheCalligrapher, можно обойтись даже без worker, если в main создать inher1 и inher2 то выбрасывается исключение

Добавлено через 32 минуты
TheCalligrapher, моя ошибка была глупая, но в то же время я нашел слабость в коде, у меня в деструкторе класса base(trader) было tpool.StopPool() что производило к исключению, я понимаю что я сделал неправильно поместив такое в деструктор и сделав выброс исключения из класса потоков
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13184 / 6820 / 1821
Регистрация: 18.10.2014
Сообщений: 17,260
21.01.2021, 20:54
Цитата Сообщение от ReYalp Посмотреть сообщение
у меня в деструкторе класса base(trader) было tpool.StopPool() что производило к исключению, я понимаю что я сделал неправильно поместив такое в деструктор и сделав выброс исключения из класса
Я это сразу заметил. Но вы сказали, что исключение выбрасывалось из конструктора ThreadPool.

Каким образом к этому моменту мог вдруг отработать деструктор Base? К этому моменту еще ни одного inner1 и inner2 даже не создано, не говоря уже о каких-то деструкторах.
0
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
21.01.2021, 20:55  [ТС]
TheCalligrapher, я пришел к этому выводу исходя из "ручного дебага", я почему-то забыл о существовании gdb, с дебагером всё стало проще, я так понимаю такие вещи как pool.start() и pool.stop() лучше делать в main?
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
21.01.2021, 21:29
Цитата Сообщение от ReYalp Посмотреть сообщение
void ThreadPool::StopPool() {
stop = true;
Надо блокировать мьютекс, когда делаешь stop = true, а то будет дедлок

Добавлено через 1 минуту
Цитата Сообщение от ReYalp Посмотреть сообщение
я так понимаю такие вещи как pool.start() и pool.stop() лучше делать в main?
Если ты наследуешься от класса, содержащего пул потоков, то надо делать StopPool() в деструкторе каждого наследника. В деструкторе базового класса недостаточно.
0
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
21.01.2021, 21:37  [ТС]
oleg-m1973, этот клас не содержит пул,пул глобальный

Добавлено через 2 минуты
oleg-m1973, а откуда дедлок возьмётся ?есть шанс что сделаю stop = true между блоком мьютекса и cv.wait?

Добавлено через 2 минуты
Хотя даже так не получится дедлока,не понимаю откуда он может взяться
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
21.01.2021, 21:43
Цитата Сообщение от ReYalp Посмотреть сообщение
oleg-m1973, а откуда дедлок возьмётся ?есть шанс что сделаю stop = true между блоком мьютекса и cv.wait?
Есть шанс, что stop = true и cv.notify_all() пройдут между while (!stop) и cv.wait(

Добавлено через 1 минуту
Цитата Сообщение от ReYalp Посмотреть сообщение
std::unique_lock<std::mutex> ul(mtx); //unique_lock is used for condition var
Кстати, while (!stop) тоже должна быть под блокировкой. Вынеси это за цикл.

Добавлено через 1 минуту
Цитата Сообщение от ReYalp Посмотреть сообщение
Хотя даже так не получится дедлока,не понимаю откуда он может взяться
Теперь будешь знать, когда он возникнет

Добавлено через 3 минуты
Хотя, у тебя там есть ещё одна проверка на стоп, под блокировкой. Можно было и одной обойтись.
0
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
21.01.2021, 21:47  [ТС]
oleg-m1973,
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Хотя, у тебя там есть ещё одна проверка на стоп, под блокировкой. Можно было и одной обойтись.
именно она и нужна для этой ситуации
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Есть шанс, что stop = true и cv.notify_all() пройдут между while (!stop) и cv.wait(
здесь не нужен мьютекс, в любом случае не будет дедлока
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
21.01.2021, 21:50
Цитата Сообщение от ReYalp Посмотреть сообщение
здесь не нужен мьютекс, в любом случае не будет дедлока
Будь уверен, будет.
cv.notify_all() работает только для потоков, которые стоят в cv.wait(). Вызывать раньше её бесполезно. Если всё это у тебя пройдёт после проверки условий, но до того, как поток встанет в cv.wait(), то будет дедлок.
0
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
21.01.2021, 21:52  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Будь уверен, будет.
cv.notify_all() работает только для потоков, которые стоят в cv.wait(). Вызывать раньше её бесполезно. Если всё это у тебя пройдёт после проверки условий, но до того, как поток встанет в cv.wait(), то будет дедлок.
если stop = true и notify_all произойдет до wait то wait вернет true тк он проверяет stop и далее в if(stop) return закончит поток
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
21.01.2021, 21:57
Блокировка мьютекса как раз гарантирует, что ты либо условия проверишь до того, как встанешь в wait, либо уже будешь там стоят и notify_all разбудит поток.

Добавлено через 44 секунды
Цитата Сообщение от ReYalp Посмотреть сообщение
если stop = true и notify_all произойдет до wait то wait вернет true тк он проверяет stop и далее в if(stop) return закончит поток
Нет, не вернёт. Он будет ждать следующего notify_all

Добавлено через 4 минуты
Цитата Сообщение от ReYalp Посмотреть сообщение
cv.wait(ul, [this]() { //wait for tasks or stop of the programm
return !tasks.empty() || stop;
});
Этот wait с предикатом - не атомарная функция, она реализована через такой же цикл while https://en.cppreference.com/w/... iable/wait. Там-то и зависнет.
0
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
21.01.2021, 22:04  [ТС]
oleg-m1973,
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <thread>
#include <condition_variable>
#include <mutex>
 
std::mutex m;
std::condition_variable cv;
bool stop = false;
 
void test(){
    std::unique_lock<std::mutex> ul(m);
    cv.wait(ul ,[](){
        return stop;
    });
    std::cout << "TEST PASSED\n";
}
 
int main(){
    stop = true;
    std::thread t(test);
    t.join();
    return 0;
}
Добавлено через 4 минуты
oleg-m1973,
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Там-то и зависнет.
не могу понять почему она должна зависнуть, хоть убей, если stop = true дo wait то что мешает wait сразу выйти из цикла тк предикат вернет true?
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
21.01.2021, 22:04
ReYalp, что ты пытаешься здесь продемонстрировать?
Кстати, вот здесь у меня есть реализация примерно такого же пула потоков https://www.cyberforum.ru/blog... g5939.html
0
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
21.01.2021, 22:06  [ТС]
oleg-m1973, я пытаюсь продемонстрировать что если переменная поменяется до входа в wait то wait успешно завершится, он впадает в режим ожидания (тем самым разблокировав мьютекс) только если первый вызов этого предиката вернет false, что невозможно тк stop была true еще до его вызова
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
21.01.2021, 22:08
Цитата Сообщение от ReYalp Посмотреть сообщение
не могу понять почему она должна зависнуть, хоть убей, если stop = true дo wait то что мешает wait сразу выйти из цикла тк предикат вернет true?
1-й поток - заходит в cw.wait(lock, []() ...........), которая с предикатом
1-й - внутри cw.wait с предикатом проверяет stop, stop == false
2-й поток - делает stop = true
2-й - вызывает cv.notify_all()
1-й - заходит в cw.wait(lock), которая без предиката, разблокирует мьютекс и засыпает
2-й - бесконечно стоит в join
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
21.01.2021, 22:08
Помогаю со студенческими работами здесь

Можно ли сделать пуш проекта на одном компе и сразу запустить пул на другом?
Можно ли сделать пуш проекта на одном компе и сразу запустить пул на другом? Ну... есть такая задача типа. Можно ли как-то команду...

Пул потоков
Всем привет! Подскажите, пожалуйста, кто реализовывал/использовал пулы потоков, как вы это делали? Заранее благодарю за ответ.

Пул потоков
Здравствуйте. Допустим, у нас есть массив из 1000 элементов и n потоков, которые должны обработать этот массив, но каждый поток должен...

Пул потоков
есть код, while(Parser::mailsCount&lt;MAX) { boost::mutex io_mutex; boost::thread_group group; for (int i = 0; i &lt;...

Остановить пул потоков
Добрый день. Есть такая проблема: Создается пул потоков, 2 потока выводят информацию в listbox и при нажатии кнопки Stop завершают свою...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
Использование значений реквизитов справочника в документе, с определенными условиями и правами
Maks 07.04.2026
1. Контроль срока действия договора Алгоритм из решения ниже реализован на примере нетипового документа "ЗаявкаНаРаботу", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если. . .
Доступность команды формы по условию
Maks 07.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: сделать доступной кнопку (команда формы "ЗавершитьСписание") при. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru