Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 10.06.2012, 21:08   #1
Лета
Пользователь
 
Регистрация: 10.06.2012
Сообщений: 44
По умолчанию Поток и функция

Здравствуйте.
Есть функция вида :
Код:
DWORD WINAPI Thread1(LPVOID lp)
{

	HWND hWnd = (HWND)lp;
		SetWindowText(hWnd, L"Begin");
		Sleep(1000);
		SetWindowText((HWND)lp, L"End");
	return 0;
}
Почему, если вызывать ее как обычную функцию, то программка подвиснет на секунду и выведет сразу "End", а если сделать ее входной потоковой функцией, то отработает корректно: сначала выведет "Begin", и только потом "End"?

Последний раз редактировалось Лета; 10.06.2012 в 21:38.
Лета вне форума Ответить с цитированием
Старый 10.06.2012, 21:15   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Да потому что ты вызывая ее из главного потока заставляешь функцией Sleep засыпать этот самый главный поток.
Вызывая же из сопроцесса засыпает только этот сопроцесс, а главный поток продолжает работать.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 10.06.2012, 21:21   #3
Лета
Пользователь
 
Регистрация: 10.06.2012
Сообщений: 44
По умолчанию

Почему это влияет на то, что сначала еще до вызова Sleep не отображается слово "Begin"?
Лета вне форума Ответить с цитированием
Старый 10.06.2012, 22:22   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

А смотря где ты его вызываешь... Может строка эта успела присвоится заголовку окна, но само окно не успело перерисоваться, а ты уже присваиваешь вторую строку.
Sleep() в твоем случае при вызове из главного потока и перерисовку тоже остановит.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 10.06.2012, 22:40   #5
Лета
Пользователь
 
Регистрация: 10.06.2012
Сообщений: 44
По умолчанию

Вызываю в обработчике нажатия на кнопку.
А почему тогда,если эту функцию сделать входной потоковой, то окно успевает перерисовываться?

Извините, если задаю глупый вопрос, но для меня очень важно разобраться, и спасибо что помогаете мне.
Лета вне форума Ответить с цитированием
Старый 11.06.2012, 00:56   #6
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

отрисовкой занимается только главный поток (обычно)

если делать Sleep() в главном потоке, то и отрисовка не будет в это время выполнятся, т.к. главный поток спит

если же делать то же самое в отдельном потоке, то главный будет спокойно отрисовывать, пока отдельные потоки занимаются своими делами (спят и т.д.)
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 11.06.2012, 01:25   #7
Лета
Пользователь
 
Регистрация: 10.06.2012
Сообщений: 44
По умолчанию

Спасибо огромное!
Лета вне форума Ответить с цитированием
Старый 11.06.2012, 01:39   #8
Лета
Пользователь
 
Регистрация: 10.06.2012
Сообщений: 44
По умолчанию

А вот немного другая функция вида :

Код:
DWORD WINAPI Thread2(LPVOID lp)
{

	HWND hWnd = (HWND)lp;
	for(int i=0;i<5000;++i)
	{
		TCHAR buf[10];
		wsprintf(buf,L"%d",i);
		SetWindowText(hWnd,buf);
	}
	return 0;
}
С ней ситуация та же: если вызывать как обычную функцию - зависнет немного, и выведет сразу 499, а если вызывать в отдельном потоке - будет видно как выводит каждое число.
Здесь уже нет Sleep, но получается что очень много раз окно перерисовывается, и так как в первом случае все делается в одном потоке - не успевает нормально перерисоваться, а во втором случае - работает два потока, поэтому все корректно отображается. Я правильно поняла?
Лета вне форума Ответить с цитированием
Старый 11.06.2012, 02:05   #9
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

не совсем. Чтобы что-то отрисовалось на экране, главный поток (обычно это делает он) должен регулярно выгребать из очереди сообщений очередые сообщения и обрабатывать их. Вы, со своим циклом (точто так же, как и со Sleep()), не оставляете главному потоку никаких шансов заняться этой обработкой. Не может поток приостановить на время ваш цикл, обработать сообщения и вернуться обратно.

В Дельфи есть такой кривой костыль, который любят использовать на втором дне программирования: Application.ProcessMessages(). Этот костыль надо вызывать руками, когда есть чувство, что что-то не так с гуем. Этот метод как раз и позволяет главному потоку выгрести накопившиеся сообщения и прорисовать гуй.

В С++ такими извращениями обычно не страдают, а сразу отправляют длительную работу с данными (сокетами, файлами и прочее) в дополнительные потоки, оставляя главному потоку полную свободу наслаждаться работой с сообщениями и гуем.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 11.06.2012, 02:24   #10
Лета
Пользователь
 
Регистрация: 10.06.2012
Сообщений: 44
По умолчанию

Я думала, что все происходит так: идет обработка сообщения и нужно что-то вывести на экран - в очередь помещается сообщение WM_PAINT, но оно не будет обработано, пока не закончится обработка текущего сообщения.Обработка закончится, и только после этого процессор примется а обработку WM_PAINT. Но так как (в случае второй функции) там их накопилось сразу 500 - процессор каждое обрабатывает, но все происходит так быстро, что можно увидеть только конечный результат - т.е. число 499. Я снова не так поняла?
Лета вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Класс запускает поток, который заполняет этот класс. Обмен класс <=> поток. Человек_Борща Общие вопросы Delphi 8 27.02.2012 23:24
[Проблема] - Прервать закачку, закрыть поток(tthread) Функция(WinInet) Человек_Борща Работа с сетью в Delphi 0 14.12.2010 20:21
Поток. Не получается создать поток. Выдает ошибки при запуске bigory Общие вопросы по Java, Java SE, Kotlin 3 23.09.2010 00:40
поток Артэс Общие вопросы C/C++ 3 09.12.2009 22:20
одна функция потока, а другая функция - член класса запускающего этот поток Дмитрий_Ч Общие вопросы C/C++ 2 27.09.2007 08:50