Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
NeonLost
Пес войны
75 / 86 / 3
Регистрация: 23.02.2012
Сообщений: 653
#1

Deadlock и racecondition проверить код - C++

21.07.2014, 07:40. Просмотров 550. Ответов 8
Метки нет (Все метки)

класс принимает функцию и количество потоков...и все время поддерживает одновременное выполнение 10 потоков этой функции...интересуют ошибки связанные с многопоточным программированием...может еще подскажите как лучше сделать?..)

заголовочный файл
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class gthread
{
    typedef void (*pFunc) ();
public:
    gthread(pFunc func, unsigned short int, unsigned short int);
    ~gthread();
    void start();
    void stop();
private:
    pFunc _func;
    std::mutex _mut;
    unsigned short int _threadCounter;
    unsigned short int _threadNumber;
    unsigned short int _breakTime; //milliseconds
    bool _condition;
    void invoker();
    void abuse();
};
срр файл
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
void gthread::invoker()
{
    (_func)();
}
 
gthread::gthread(pFunc func, unsigned short int threadNumber, unsigned short int breakTime = 100 )
{
    _func= func;
    _threadNumber = threadNumber;
    _threadCounter = 0;
    _breakTime = breakTime;
    _condition = true;
}
 
gthread::~gthread()
{
}
 
void gthread::start()
{
    std::thread abuser(&gthread::abuse, this);
    abuser.detach();
}
 
void gthread::abuse()
{
    while(_condition)
    {
        while(_threadCounter<_threadNumber) 
        {
            std::async([this]
            {
                _mut.lock();
                _threadCounter++;
                _mut.unlock();
                std::thread t(&gthread::invoker, this);
                t.join();
                _mut.lock();
                _threadCounter--;
                _mut.unlock();
            });
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(_breakTime));
    }
}
 
void gthread::stop()
{
    _condition = false;
}
тест
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void StartThread()
{
    //std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        cout<<std::this_thread::get_id()<<endl;
}
 
int main()
{
    gthread q(&StartThread, 10);
    q.start();
    std::this_thread::sleep_for(std::chrono::seconds(100));
    q.stop();
    getchar();
    return 0;
}
Добавлено через 6 часов 55 минут
особенно интересны строки 30-40...)
так вроде все работает...)

Добавлено через 10 часов 39 минут
ну хоть кто-нибудь...)
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.07.2014, 07:40
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Deadlock и racecondition проверить код (C++):

Проверить код - C++
#include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;string&gt; #include &lt;cctype&gt; int _tmain(int argc, _TCHAR* argv) { ...

проверить код на с++ - C++
проверьте код, а то не могу понять в чем ошибка, почему не запускается #include &lt;iostream.h&gt; #include &lt;math.h&gt; #include...

Проверить код - C++
Пытаюсь переделать программу из С# в C++. { protected int x; protected int y; public virtual void Show () / /...

Проверить код - C++
Всем здравствуйте. Ребят, не могли бы посмотреть и поправить программу, а то выдает ошибку: Compiling... d:\program...

Проверить код - C++
Предоставляемые целые числа с1, ... с9. Есть ли в этой последовательности три подряд стоящих нулевых элементов. Если есть, то напечатать их...

Проверить код - C++
не внятный вывод на экран #include &quot;stdafx.h&quot; #include &lt;Windows.h&gt; #include &lt;conio.h&gt; struct TStudentData { int Num; ...

8
Ilot
Модератор
Эксперт С++
1823 / 1181 / 232
Регистрация: 16.05.2013
Сообщений: 3,118
Записей в блоге: 5
Завершенные тесты: 1
21.07.2014, 08:53 #2
Цитата Сообщение от NeonLost Посмотреть сообщение
особенно интересны строки 30-40...)
Верное замечание. Не рекомендуется вызывать непосредственно функции lock и unlock свойства мьютекса. Используйте std::lock_guard. Хотя возможно в данном случае проще воспользоваться атомарным инкрементом и _threadCounter сделать атомарным типом?
Еще в конструкторе список инициализации уже не приемлим?
1
aLarman
642 / 563 / 89
Регистрация: 13.12.2012
Сообщений: 2,109
21.07.2014, 09:39 #3
Цитата Сообщение от NeonLost Посмотреть сообщение
может еще подскажите как лучше сделать?..)
посмотреть в сторону пула потоков
1
NeonLost
Пес войны
75 / 86 / 3
Регистрация: 23.02.2012
Сообщений: 653
21.07.2014, 21:00  [ТС] #4
Верное замечание. Не рекомендуется вызывать непосредственно функции lock и unlock свойства мьютекса. Используйте std::lock_guard. Хотя возможно в данном случае проще воспользоваться атомарным инкрементом и _threadCounter сделать атомарным типом?
Еще в конструкторе список инициализации уже не приемлим?
std::lock_guard тут не подойдет, если его поставить в самом начале функции, то он разлочит, когда она завершится...а на счет атомарности вы правы, спасибо...)
я не помню как сделать в списке инициаллизации значение по умолчанию...(

посмотреть в сторону пула потоков
возможно это верное решение...но я не уверен, что, например, росо::threadpool умеет выполнять такую задачу, хотя честно признаюсь ни разу не использовал...)

Добавлено через 9 минут
Цитата Сообщение от Ilot Посмотреть сообщение
Верное замечание. Не рекомендуется вызывать непосредственно функции lock и unlock свойства мьютекса. Используйте std::lock_guard. Хотя возможно в данном случае проще воспользоваться атомарным инкрементом и _threadCounter сделать атомарным типом?
Еще в конструкторе список инициализации уже не приемлим?
на самом деле я немного изменил код, чтоб быть точно уверенным, что поток запустится сразу после выполнения предыдущего, а не спустя какое-то время и не гоняя в холостую процессор...и надобность в этом мьютексе сразу отпала
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void gthread::abuse()
{
    while(_threadCounter<_threadNumber) 
    {
        _threadCounter++;
        std::async([this]
        {
            while(_condition)
            {
                std::thread t(&gthread::invoker, this);
                t.join();
            }
        });
    }
}
все же интересно на сколько это работает, и на сколько это велосипед...)
особенно интересно, нужно ли делать атомарной переменную _condition и что будет, если я из меин потока поменяю ее значение...)
0
Убежденный
Ушел с форума
Эксперт С++
15697 / 7207 / 1139
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
21.07.2014, 22:32 #5
Цитата Сообщение от NeonLost Посмотреть сообщение
while(_condition)
Может крутиться вечно.
Типа такого:
Assembler
1
2
3
4
5
6
mov eax, dword ptr[_condition]
 
@loop:
cmp eax, 0
...
jmp @loop
1
aLarman
642 / 563 / 89
Регистрация: 13.12.2012
Сообщений: 2,109
21.07.2014, 22:33 #6
Цитата Сообщение от NeonLost Посмотреть сообщение
росо::threadpool умеет выполнять такую задачу
в лбюбой книге по параллельному программированию рассказано как сделать пул самому, там нужна очередь с мьютексами и несколько потоков, и все
1
NeonLost
Пес войны
75 / 86 / 3
Регистрация: 23.02.2012
Сообщений: 653
21.07.2014, 22:47  [ТС] #7
Может крутиться вечно.
Типа такого:
Код ASM

mov eax, dword ptr[_condition]

@loop:
cmp eax, 0
...
jmp @loop
получается при определенных настройках оптимизатора, может не прокатить?..(
_condition поместить в кучу, а не в стек, то спасет?..)
0
Убежденный
Ушел с форума
Эксперт С++
15697 / 7207 / 1139
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
21.07.2014, 22:51 #8
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от NeonLost Посмотреть сообщение
_condition поместить в кучу, а не в стек, то спасет?..)
Без разницы.
С _condition нужно обращаться специальным образом.
Например, в Visual C++ ее достаточно сделать volatile, это заставит
компилятор каждый раз при обращении программы к переменной
перечитывать ее из памяти.
1
NeonLost
Пес войны
75 / 86 / 3
Регистрация: 23.02.2012
Сообщений: 653
22.07.2014, 20:04  [ТС] #9
Без разницы.
С _condition нужно обращаться специальным образом.
Например, в Visual C++ ее достаточно сделать volatile, это заставит
компилятор каждый раз при обращении программы к переменной
перечитывать ее из памяти.
спасибо большое...сразу не подумал бы...)

Добавлено через 1 минуту
а еще у меня цитаты не взлетают почему-то...(

Добавлено через 11 минут
если кому-то интересно про volatile, то алена c++ неплохо показала пример, один в один как у меня...)
Компилятор скорее всего оптимизирует код вроде такого, если переменная cancel не менялась в теле цикла.


bool cancel = false;
while( !cancel ) {
;
}

Если cancel не меняется, то ее и проверять каждый раз незачем, компилятор и не будет ее проверять.

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

volatile bool cancel = false;
while( !cancel ) {
;
}
Добавлено через 6 минут
еще довольно важный момент, который я проморгал
C++
1
2
3
4
5
6
7
8
std::async(std::launch::async, [this]
        {
            while(_condition)
            {
                std::thread t(&gthread::invoker, this);
                t.join();
            }
        });
если std::async в параметрах не указать std::launch::async, то она будет запускать потоки на свое усмотрение(некоторые с lazy init)

Добавлено через 24 минуты
пока класс находится в таком состоянии...интересны еще мнения...)

заголовок
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
#include <thread>
#include <future>
 
class gthread
{
    typedef void        (*pFunc) ();
 
public:
    gthread(pFunc func, unsigned short int threadNumber): 
    _func               (func), 
    _threadNumber       (threadNumber),
    _threadCounter      (0),
    _breakTime          (breakTime),
    _condition          (true)  {}
    void start();
    void stop();
 
private:
    pFunc               _func;
    unsigned short int  _threadCounter;
    unsigned short int  _threadNumber;
    volatile bool       _condition;
    void invoker();
    void abuse();
};
код
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
#include "gthread.h"
 
void gthread::start()
{
    std::thread abuser(&gthread::abuse, this);
    abuser.detach();
}
 
void gthread::stop()
{
    _condition = false;
}
 
void gthread::invoker()
{
    (_func)();
}
 
 
void gthread::abuse()
{
    while(_threadCounter<_threadNumber) 
    {
        _threadCounter++;
        std::async(std::launch::async, [this]
        {
            while(_condition)
            {
                std::thread t(&gthread::invoker, this);
                t.join();
            }
        });
    }
}
Добавлено через 20 часов 15 минут
ап...)
0
22.07.2014, 20:04
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.07.2014, 20:04
Привет! Вот еще темы с ответами:

Проверить код на правильность - C++
Здравствуйте! Помогите пожалуйста проверить код на правильность,т.к. почему-то не компилируется. Задача: Известно кол-во очков, набранных...

Проверить код на правильность - C++
Ребят написала код но не уверена что правильно.К сожалению Как проверить не знаю. проверьте пожалуйста заранее благодарю! #include...

Проверить код на корректность - C++
Сделал лабу, все работает отлично.... Но я не уверен что она написана нормально, может где то переменная не там обявляется или не так...

Проверить код на правильность - C++
#include &lt;iostream&gt; using namespace std; int main() { setlocale(LC_CTYPE,&quot;Russian&quot;); cout &lt;&lt; &quot;\n Введите...


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

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

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