boost::thread
От: nervous Украина  
Дата: 19.06.04 18:41
Оценка:
Hi all.

Есть рабочий поток с вычислениями.
Есть модальное диалоговое окно для отображения прогресса.
Надо дать пользователю возможность прервать поток.
Как правильно это сделать?
Re: boost::thread
От: Нахлобуч Великобритания https://hglabhq.com
Дата: 19.06.04 18:49
Оценка:
Здравствуйте, nervous, Вы писали:

N>Hi all.


N>Есть рабочий поток с вычислениями.

N>Есть модальное диалоговое окно для отображения прогресса.
N>Надо дать пользователю возможность прервать поток.
N>Как правильно это сделать?

Э-эх!.. Как оно там... Если вычисления в цикле (а так оно скорей всего и есть), то как-то так:

for(whatever)
{
    // Вычисления
    if(WAIT_OBJECT_0 == ::WaitForSingleObject(g_hStopCalculations, 0))
        return;
} // for
HgLab: Mercurial Server and Repository Management for Windows
Re: boost::thread
От: Azir Беларусь  
Дата: 19.06.04 22:31
Оценка: 1 (1)
Здравствуйте, nervous, Вы писали:

N>Hi all.


N>Есть рабочий поток с вычислениями.

N>Есть модальное диалоговое окно для отображения прогресса.
N>Надо дать пользователю возможность прервать поток.
N>Как правильно это сделать?

Можно, например, так:


#include <boost/thread/mutex.hpp>
#include <boost/thread.hpp>

void DoCalculations(int i);
void UpdateProgress(int i);
bool IsUserReadyToExit();

int const stepsNumber = 10;
boost::mutex monitor;
bool goingToExit = false;

void WorkThread()
{
    for (int i = 0; i < stepsNumber; ++i)
    {
        DoCalculations(i);
        {
            boost::mutex::scoped_lock lk(monitor);
            if (goingToExit)
                return;
        }
        UpdateProgress(i);
    }
}

int main()
{
    boost::thread workThread(WorkThread);
    while (!IsUserReadyToExit()) {}
    {
        boost::mutex::scoped_lock lk(monitor);
        goingToExit = true;
    }
    workThread.join();
}
Re: boost::thread
От: maq Россия http://www.maqdev.com
Дата: 20.06.04 13:29
Оценка: 2 (1)
Здравствуйте, nervous, Вы писали:

N>Hi all.


N>Есть рабочий поток с вычислениями.

N>Есть модальное диалоговое окно для отображения прогресса.
N>Надо дать пользователю возможность прервать поток.
N>Как правильно это сделать?


http://www.rsdn.ru/Forum/Message.aspx?mid=638858&amp;only=1
Автор: maq
Дата: 13.05.04
... << Rsdn@Home 1.1.4 beta 1 >>
Re[2]: boost::thread
От: Denwer Россия  
Дата: 21.06.04 06:19
Оценка:
Здравствуйте, Azir, Вы писали:

A>Здравствуйте, nervous, Вы писали:


N>>Hi all.


N>>Есть рабочий поток с вычислениями.

N>>Есть модальное диалоговое окно для отображения прогресса.
N>>Надо дать пользователю возможность прервать поток.
N>>Как правильно это сделать?

A>Можно, например, так:



A>
A>#include <boost/thread/mutex.hpp>
A>#include <boost/thread.hpp>

A>void DoCalculations(int i);
A>void UpdateProgress(int i);
A>bool IsUserReadyToExit();

A>int const stepsNumber = 10;
A>boost::mutex monitor;
A>bool goingToExit = false;

A>void WorkThread()
A>{
A>    for (int i = 0; i < stepsNumber; ++i)
A>    {
A>        DoCalculations(i);
A>        {
A>            boost::mutex::scoped_lock lk(monitor);
A>            if (goingToExit)
A>                return;
A>        }
A>        UpdateProgress(i);
A>    }
A>}

A>int main()
A>{
A>    boost::thread workThread(WorkThread);
A>    while (!IsUserReadyToExit()) {}
A>    {
A>        boost::mutex::scoped_lock lk(monitor);
A>        goingToExit = true;
A>    }
A>    workThread.join();
A>}
A>


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

Не ужто нет переносимого решения для Intelocked функций?
Re[3]: boost::thread
От: Patalog Россия  
Дата: 21.06.04 08:11
Оценка:
Здравствуйте, Denwer, Вы писали:

хъ

D>Я конечно не знаю как там в юниксах это делается, может и так, но в виндах это слишком расточительно, обертывать одну переменную мьютексом.


Для виндов mutex::scoped_lock==CRITICAL_SECTION
Почетный кавалер ордена Совка.
Re[4]: boost::thread
От: Denwer Россия  
Дата: 21.06.04 08:33
Оценка:
Здравствуйте, Patalog, Вы писали:

P>Здравствуйте, Denwer, Вы писали:


P>хъ


D>>Я конечно не знаю как там в юниксах это делается, может и так, но в виндах это слишком расточительно, обертывать одну переменную мьютексом.


P>Для виндов mutex::scoped_lock==CRITICAL_SECTION


Это тоже расточительно по сравнения с интерлокед функциями.
Re[5]: boost::thread
От: _Winnie Россия C++.freerun
Дата: 21.06.04 08:49
Оценка:
Здравствуйте, Denwer, Вы писали:

D>Это тоже расточительно по сравнения с интерлокед функциями.


Не, не расточительно, в том случае, если переменную фактически использует только один поток и они не пытаются использовать ее одновременно. Тогда EnterCriticalSecton — просто десяток ассеблерных команд без всяких жутких усыплений.
Правильно работающая программа — просто частный случай Undefined Behavior
Re[6]: boost::thread
От: Denwer Россия  
Дата: 21.06.04 08:54
Оценка:
Здравствуйте, _Winnie, Вы писали:

_W>Здравствуйте, Denwer, Вы писали:


D>>Это тоже расточительно по сравнения с интерлокед функциями.


_W>Не, не расточительно, в том случае, если переменную фактически использует только один поток и они не пытаются использовать ее одновременно. Тогда EnterCriticalSecton — просто десяток ассеблерных команд без всяких жутких усыплений.


Круто круто, и зачем тогда вообще нужна критическая секция для одного потока.
Re[5]: boost::thread
От: Patalog Россия  
Дата: 21.06.04 09:21
Оценка:
Здравствуйте, Denwer, Вы писали:

[]

boost::detail::lightweight_mutex?
Почетный кавалер ордена Совка.
Re[2]: boost::thread - нафига он нужен ?...
От: Kalinsky V. http://www.promzona.design.ru
Дата: 21.06.04 09:43
Оценка:
Здравствуйте, Azir, Вы писали:

A>Можно, например, так:


A>[ccode]

A>#include <boost/thread/mutex.hpp>
A>#include <boost/thread.hpp>

A> DoCalculations(i);

A> {
A> boost::mutex::scoped_lock lk(monitor);
A> if (goingToExit)
A> return;
A> }
A> UpdateProgress(i);
A> }
A> boost::thread workThread(WorkThread);
A> while (!IsUserReadyToExit()) {}
A> {
A> boost::mutex::scoped_lock lk(monitor);
A> goingToExit = true;


Решил в отдельную тему вопрос не выводить (забьют минусами :) ). Смотрю на эту возню с бустом и не понимаю, зачем огород городить ? Почему не написать CreateThread(...., WorkThread, &dw) вместо boost::thread workThread(WorkThread) ? Чем лучше буст ? У меня одно объяснение: переносимость кода. Или я не прав ?
Цель деятельности всех программистов – чтобы их деятельность стала не нужна.
Re[6]: boost::thread
От: Denwer Россия  
Дата: 21.06.04 09:51
Оценка:
Здравствуйте, Patalog, Вы писали:

P>Здравствуйте, Denwer, Вы писали:


P>[]


P>boost::detail::lightweight_mutex?


Это тоже не то. Это реализация функционала мьютекса через интерлокед функции. Что совсем отличное от самих интерлокед функций.

ЗЫ: lightweight_mutex через интерлокед функции отстой

while( InterlockedExchange(&m_.l_, 1) )
{
 Sleep(1);
}


Этож надо было такое написать.
Неудосужилиись даже volatile поставить перед long l_;

Короче
Re[7]: boost::thread
От: Patalog Россия  
Дата: 21.06.04 10:21
Оценка:
Здравствуйте, Denwer, Вы писали:

хъ

D>Это тоже не то. Это реализация функционала мьютекса через интерлокед функции. Что совсем отличное от самих интерлокед функций.


А какое отношение это имеет к рассматриваемому вопросу?

D>
D>while( InterlockedExchange(&m_.l_, 1) )
D>{
D> Sleep(1);
D>}
D>


D>Этож надо было такое написать.


А что, собст. не так? Возврат значения InterlockedExchange нихрена не атомарно, в отличии от собственно Exchange.
Подход с циклом много где применяется, напр. Handy Features in Windows, and Interlocked Functions

D>Неудосужилиись даже volatile поставить перед long l_;


Хм, может конечно и надо бы поставить, но ведь оно по значению не меняется, а только по указателю...
Почетный кавалер ордена Совка.
Re[8]: boost::thread
От: Denwer Россия  
Дата: 21.06.04 10:32
Оценка:
Здравствуйте, Patalog, Вы писали:

P>Здравствуйте, Denwer, Вы писали:


P>хъ


D>>Это тоже не то. Это реализация функционала мьютекса через интерлокед функции. Что совсем отличное от самих интерлокед функций.


P>А какое отношение это имеет к рассматриваемому вопросу?


К первому посту никакого отношения не имеет, а дольше было предложено решение
boost::mutex::scoped_lock lk(monitor);
if (goingToExit)
    return;


Я и сказал что это очень не эффективно, даже если там будет критическая секция, для этого примера самое то использовать интерлокед функции.

D>>
D>>while( InterlockedExchange(&m_.l_, 1) )
D>>{
D>> Sleep(1);
D>>}
D>>


D>>Этож надо было такое написать.


P>А что, собст. не так? Возврат значения InterlockedExchange нихрена не атомарно, в отличии от собственно Exchange.

P>Подход с циклом много где применяется, напр. Handy Features in Windows, and Interlocked Functions

Это как так? Не понял?

Может они и применяются, но у это явно не лучшее решение для быстрого мьютекса.

D>>Неудосужилиись даже volatile поставить перед long l_;


P>Хм, может конечно и надо бы поставить, но ведь оно по значению не меняется, а только по указателю...
Re[9]: boost::thread
От: Patalog Россия  
Дата: 21.06.04 11:08
Оценка:
Здравствуйте, Denwer, Вы писали:

хъ

P>>А что, собст. не так? Возврат значения InterlockedExchange нихрена не атомарно, в отличии от собственно Exchange.

P>>Подход с циклом много где применяется, напр. Handy Features in Windows, and Interlocked Functions

D>Это как так? Не понял?


Имелось в виду то, что в
long ret = InterlockedExchange(&target, 1);

InterlockedExchange может вернуть 1. А нам нужен именно 0, чтобы быть уверенным, что никто другой не владеет мьютексом.

D>Может они и применяются, но у это явно не лучшее решение для быстрого мьютекса.


Критикуя — предлагай! Как бы ты реализовал lightweight_mutex?
Почетный кавалер ордена Совка.
Re[10]: boost::thread
От: Denwer Россия  
Дата: 21.06.04 11:50
Оценка:
Здравствуйте, Patalog, Вы писали:

P>Здравствуйте, Denwer, Вы писали:


P>хъ


P>>>А что, собст. не так? Возврат значения InterlockedExchange нихрена не атомарно, в отличии от собственно Exchange.

P>>>Подход с циклом много где применяется, напр. Handy Features in Windows, and Interlocked Functions

D>>Это как так? Не понял?


P>Имелось в виду то, что в

P>
P>long ret = InterlockedExchange(&target, 1);
P>

P>InterlockedExchange может вернуть 1. А нам нужен именно 0, чтобы быть уверенным, что никто другой не владеет мьютексом.

Кстати именно об этой проблеме писал насколько я помню Рихтер где то.

D>>Может они и применяются, но у это явно не лучшее решение для быстрого мьютекса.


P> Критикуя — предлагай! Как бы ты реализовал lightweight_mutex?


Решение одно, через критические секции.
Re: boost::thread
От: kzua  
Дата: 21.06.04 13:42
Оценка: -1
Здравствуйте, nervous, Вы писали:

N>Hi all.


N>Есть рабочий поток с вычислениями.

N>Есть модальное диалоговое окно для отображения прогресса.
N>Надо дать пользователю возможность прервать поток.
N>Как правильно это сделать?

Я смотрю тут у ребят мозги совсем затекли.
Вот самое простое, эффективное и верное решение.

BYTE nbDoCalc = 1;
HANDLE hThread; // = _beginthreadex
HWND hwndProgressBar;

void WorkThread()
{

while( nbDoCalc )
{
// Do Job
// SendMessage -> hwndProgressBar
...
};
};



MyDlgBox::OnStopCalc()
{
nbDoCalc = 1;

// ждем когда тред реально завершится
WaitForSingleObject( hThread, INFINITE );
};


Будет работать даже в многопроцессорном
окружении.


WBR, Alexei K.
Re[3]: boost::thread - нафига он нужен ?...
От: kzua  
Дата: 21.06.04 13:45
Оценка:
Здравствуйте, Kalinsky V., Вы писали:

KV>Здравствуйте, Azir, Вы писали:


A>>Можно, например, так:


A>>[ccode]

A>>#include <boost/thread/mutex.hpp>
A>>#include <boost/thread.hpp>

A>> DoCalculations(i);

A>> {
A>> boost::mutex::scoped_lock lk(monitor);
A>> if (goingToExit)
A>> return;
A>> }
A>> UpdateProgress(i);
A>> }
A>> boost::thread workThread(WorkThread);
A>> while (!IsUserReadyToExit()) {}
A>> {
A>> boost::mutex::scoped_lock lk(monitor);
A>> goingToExit = true;


KV>Решил в отдельную тему вопрос не выводить (забьют минусами ). Смотрю на эту возню с бустом и не понимаю, зачем огород городить ? Почему не написать CreateThread(...., WorkThread, &dw) вместо boost::thread workThread(WorkThread) ? Чем лучше буст ? У меня одно объяснение: переносимость кода. Или я не прав ?


Вот уж CreateThread действительно нельзя писать.

Только _beginthreadex !!!

WBR, Alexei K.
Re[2]: boost::thread
От: kzua  
Дата: 21.06.04 13:48
Оценка:
Здравствуйте, kzua, Вы писали:

K>Здравствуйте, nervous, Вы писали:


N>>Hi all.


N>>Есть рабочий поток с вычислениями.

N>>Есть модальное диалоговое окно для отображения прогресса.
N>>Надо дать пользователю возможность прервать поток.
N>>Как правильно это сделать?

K>Я смотрю тут у ребят мозги совсем затекли.

K>Вот самое простое, эффективное и верное решение.

K>BYTE nbDoCalc = 1;

K>HANDLE hThread; // = _beginthreadex
K>HWND hwndProgressBar;

K>void WorkThread()

K>{

K> while( nbDoCalc )

K> {
K> // Do Job
K> // SendMessage -> hwndProgressBar
K> ...
K> };
K>};



K>MyDlgBox::OnStopCalc()

K>{
K> nbDoCalc = 1;
^^^^^^^^^^^^^
nbDoCalc = 0;

K> // ждем когда тред реально завершится

K> WaitForSingleObject( hThread, INFINITE );
K>};


K>Будет работать даже в многопроцессорном

K>окружении.


WBR, Alexei K.
Re[4]: boost::thread - нафига он нужен ?...
От: ssm Россия  
Дата: 21.06.04 13:48
Оценка:
Здравствуйте, kzua, Вы писали:

K>Вот уж CreateThread действительно нельзя писать.


K>Только _beginthreadex !!!


почему?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.