Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Не срабатывает поток 
:(
    Опции темы
rudolfninja
Дата 25.10.2013, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 341
Регистрация: 19.2.2013
Где: г. Минск

Репутация: 1
Всего: 6



Доброго времени суток.
Сразу к вопросу:
Есть класс, в котором функцией run создается три потока. Потоки выполняют статические функции класса. В статическую функцию передается указатель на экземпляр класса, который вызвал ее, чтоб можно было получить доступ к общим объектам. Первый поток выводит в текстовое поле строку (разделяемый ресурс), второй - заменяет в нем одну букву на другую, третий - вторую на первую

Код

void MainWindow::run()
{
DWORD thread_id = -1;
_read_info_thread_handle = CreateThread(NULL, 0, &read_info, this, 0, &thread_id);
_a_to_b_thread_handle = CreateThread(NULL, 0, &a_to_b, this, 0, &thread_id);
_b_to_a_thread_handle = CreateThread(NULL, 0, &b_to_a, this, 0, &thread_id);
}

DWORD MainWindow::read_info(void* param)
{
    MainWindow* obj = (MainWindow*)param;
    if(!obj->get_is_buffer_exists()){
        obj->ui->log_text->append("Buffer is not exists!");
        return -1;
    }
    while(true)
    {
        QString curr_time = "[" + QTime::currentTime().toString("hh:mm:ss.zzz") + "] ";
        EnterCriticalSection(&obj->_cs);
        obj->ui->log_text->append(curr_time);
        obj->ui->log_text->append(obj->_buffer);
        LeaveCriticalSection(&obj->_cs);
        Sleep(200);
    }

    return 0;
}

DWORD MainWindow::a_to_b(void* param)
{
    MainWindow* obj = (MainWindow*)param;
    if(!obj->get_is_buffer_exists()){
        obj->ui->log_text->append("Buffer is not exists!");
        return -1;
    }
    while(true)
    {
        EnterCriticalSection(&obj->_cs);
        for(unsigned int i = 0; i < strlen(obj->_buffer); i++)
            if(tolower(obj->_buffer[i]) == 'a')
                obj->_buffer[i] = 'b';
        LeaveCriticalSection(&obj->_cs);
    }
    return 0;
}

DWORD MainWindow::b_to_a(void* param)
{
    MainWindow* obj = (MainWindow*)param;
    if(!obj->get_is_buffer_exists()){
        obj->ui->log_text->append("Buffer is not exists!");
        return -1;
    }
    while(true)
    {
        EnterCriticalSection(&obj->_cs);
        for(unsigned int i = 0; i < strlen(obj->_buffer); i++)
            if(tolower(obj->_buffer[i]) == 'b')
                obj->_buffer[i] = 'a';
        LeaveCriticalSection(&obj->_cs);
    }
    return 0;
}

После этого кода выводится только результат работы потока "б->а", результата "а->б" не видно.  Да и первый поток отрабатывает только определенное количество времени и потом перестает выполняться.
Не подскажете, в чем может быть проблема?

На всякий случай:
Код

class MainWindow : public QMainWindow
{
    Q_OBJECT
    HANDLE              _read_info_thread_handle;
    HANDLE              _a_to_b_thread_handle;
    HANDLE              _b_to_a_thread_handle;
    bool                _is_threads_created;
    bool                _is_buffer_exists;
    bool                _is_fileview_init;
    FileMapManager      _file_map_mng;
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    bool get_is_buffer_exists(){return _is_buffer_exists;}
    CRITICAL_SECTION    _cs;
    char*               _buffer;

private slots:
    void on_chose_file_button_clicked();
    void run();
private:
    Ui::MainWindow *ui;
    static DWORD WINAPI read_info(void* param);
    static DWORD WINAPI a_to_b(void* param);
    static DWORD WINAPI b_to_a(void* param);
};

PM MAIL Skype   Вверх
Dem_max
Дата 25.10.2013, 14:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 16
Всего: 39



Ну потому что такая конструкция
Код

    while(true)
    {
        EnterCriticalSection(&obj->_cs);


всегда будет вызывать дедлок для другого потока

Добавлено через 2 минуты и 53 секунды
На почитай от и до конца
ГЛАВА 8 Синхронизация потоков в пользовательском режиме

Добавлено через 3 минуты и 41 секунду
Джеффри РИХТЕР "Windows для профессионалов


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
xvr
Дата 27.10.2013, 19:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(Dem_max @  25.10.2013,  14:56 Найти цитируемый пост)
всегда будет вызывать дедлок для другого потока

Ну сама по себе не будет, а вот то, что потоки 2 и 3 молотят без передыху вполне может вызвать замораживание всего на свете  smile 
2 ТС: Вставь как минимум Sleep(...) в потоки 2 и 3

PM MAIL   Вверх
rudolfninja
Дата 28.10.2013, 12:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 341
Регистрация: 19.2.2013
Где: г. Минск

Репутация: 1
Всего: 6



Основная проблема была в том, что не вызывался InitializeCriticalSection и DeleteCriticalSection.

Спасибо за помощь.
PM MAIL Skype   Вверх
GremlinProg
Дата 28.10.2013, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(rudolfninja @  28.10.2013,  14:01 Найти цитируемый пост)
Основная проблема была в том, что не вызывался InitializeCriticalSection и DeleteCriticalSection

а у Вас тут в коде реализации конструктора и нет, т.е. инициализации объекта класса MainWindow Вы нам и не показали,
стало быть, проблемного кода ни кто и не видел, а телепаты к нам заходят не часто )


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Dem_max
Дата 29.10.2013, 07:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 16
Всего: 39



Цитата(rudolfninja @ 28.10.2013,  12:01)
Основная проблема была в том, что не вызывался InitializeCriticalSection и DeleteCriticalSection.

Спасибо за помощь.

Ты все таки почитай предложенную мной книгу.


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
rudolfninja
Дата 29.10.2013, 08:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 341
Регистрация: 19.2.2013
Где: г. Минск

Репутация: 1
Всего: 6



Цитата(Dem_max @  29.10.2013,  07:02 Найти цитируемый пост)
Ты все таки почитай предложенную мной книгу. 

Я прочитал и даже не раз. Правда, не очень понял, почему всегда будет вызываться дедлок.
PM MAIL Skype   Вверх
GremlinProg
Дата 29.10.2013, 09:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Не будет там дедлока, но время работы этих двух потоков будет "слабопрогнозируемо", т.к. один из них может вытеснять к выполнению другой. Это приведет к тому, что тот, который был вытеснен будет простаивать на какой-то итерации неопределенное время.

Из этого следует, что если какой-то "третий" поток будет опираться на результат работы вытесненного потока, то при синхронизации он будет вынужден так же простаивать. Сложится впечатление "дедлока".

А класс таких ошибок с дедлоком один.


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0766 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.