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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> вопрос по CreateThread 
:(
    Опции темы
yngwie19
Дата 30.3.2009, 23:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



всем привет. Как известно фукция CreateThread возвращает дескриптор созданного потока, но скажите зачем тогда нужен 6 -ой пераметр этой функции (идентификатор потока) Я думал. что это одно и тоже!
PM MAIL   Вверх
EvilsInterrupt
Дата 31.3.2009, 08:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

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



yngwie19, 
Господин Рихтер так думает:
Цитата

Параметр pdwThreadlD 

Последний параметр функции CreateTbread — это адрес переменной типа DWORD, в которой функция возвращает идентификатор, приписанный системой новому пото ку. (Идентификаторы процессов и но'юков рассматривались в главе 4.) 

NOTE: 
В Windows 2000 и Windows NT 4 в этом параметре можно передавать NULL (обычно так и делается). Тем самым Вы сообщаете функции, что Вас не инте ресует идентификатор потока Ilo в Windows 95/98 это приведет к ошибке, так как функция попытается записать идентификатор потока no нулевому адресу, что недопустимо. И поток не будет создан. 

Такое несоответствие между операционными системами может создать разработчикам приложений массу проблем, Допустим, Вы пишете и тестируе те программу в Windows 2000 (которая создает поток, даже если Вы передаете NULL в pdwThreadID) Но вот Вы запускаете приложение в Windows 98, и фун кция CreateThread, естественно, дает ошибку. Вывод один: тщательно тестируй те свос приложение во всех операционных системах, в которых оно будет работать

PM MAIL WWW ICQ Jabber   Вверх
yngwie19
Дата 31.3.2009, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



Я думаю, что по Windows 95/98 сейчас уже никто не работает. Значит мне впринципе этот параметр не нужен и Я могу смело ставить NULL, главное это дескриптор потока который возвращает эта функций так? 
PM MAIL   Вверх
Alca
Дата 31.3.2009, 10:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 5
Всего: 50



Мой тебе совет: не используй CreateThread т.к. будут небольшие утечки памяти (если юзаешь CRT). Юзай _beginthreadex.

Добавлено через 1 минуту и 23 секунды
Цитата

Sample _beginthreadex

The following is a sample use of _beginthreadex. In this sample, an event is created and passed as an argument. The thread checks the event in a loop and when the event is signaled (by the main thread) the thread returns. Please read the _beginthreadex() and _endthreadex() documentation; this sample assumes you have and that you are familiar with it.
Код

#if !defined(_MT)
#error _beginthreadex requires a multithreaded C run-time library.
#endif

#define STRICT 1
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <process.h>
#include <iostream>
using namespace std;

#define Second (1000)

unsigned __stdcall Thread(void *ArgList) {
HANDLE hEvent = *((HANDLE*)ArgList);
while (WaitForSingleObject(hEvent, 0) != WAIT_OBJECT_0) {
    Sleep(Second>>2); // sleep for a quarter of a second
    cout << "Waiting for signal\n";
    }
cout << "Thread ending\n";
return 0;
}

int main(int argc, char *argv[], char *envp[]) {
    int ErrorNumber, DOSErrorNumber;
    unsigned ThreadId;
    HANDLE hThread, hEvent;

// Create a manual-reset nonsignaled unnamed event
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

hThread = (HANDLE)_beginthreadex(NULL, 0, Thread, &hEvent, 0, &ThreadId);
if (hThread == 0) {
    ErrorNumber = errno;
    DOSErrorNumber = _doserrno;
    cerr << "Begin thread error: " << strerror(ErrorNumber) << '\n';
    cerr << "Begin thread DOS error code: " << DOSErrorNumber << '\n';
    return 16;
    }
cout << "Thread begun\n";

Sleep(Second<<1); // wait 2 seconds
SetEvent(hEvent); // signal thread to end
int rv = WaitForSingleObject(hThread, Second<<3); // wait up to 8 seconds
cout << "Thread wait rv " << rv << '\n';
CloseHandle(hEvent);
CloseHandle(hThread);

return 0;
}

Microsoft Knowledge Base article 132078 ("How to Use _beginthreadex() and _endthreadex()")

The KB article 132078 ("How to Use _beginthreadex() and _endthreadex()") seems to have been archived, so I will summarize here what it says. It essentially says that it is better to use _beginthreadex() and _endthreadex() and it has a sample program. My sample above is an improved version of the sample in the KB article.

Use of the Win32 APIs CreateThread() and EndThread() directly is incompatible with the C Runtime (CRT) Library. In particular, use of CreateThread() and EndThread() directly can cause loss of memory that the CRT allocates. Instead, we must use either _beginthread() and _endthread() or _beginthreadex() and _endthreadex().

The advantage of _beginthreadex() compared to _beginthread() is that _beginthreadex() provides more control and is safer. For example, with _beginthreadex(), you can:
use security information
create the thread suspended initially
get the thread identifier of the thread
use the thread handle after the thread completes, allowing use of the the synchronization APIs (as above) for the thread

The advantage of _endthreadex() compared to _endthread() is that _endthreadex() is more flexible.



--------------------
PM WWW ICQ Skype Jabber   Вверх
yngwie19
Дата 31.3.2009, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



Цитата(Alca @  31.3.2009,  10:44 Найти цитируемый пост)
не используй CreateThread т.к. будут небольшие утечки памяти 

В чем выражаются эти утечки памяти.
Я пока что тока начал разбираться с потоками поэтому в книге приводится именно эта функция. 
А что насчет 
Цитата(yngwie19 @  31.3.2009,  10:36 Найти цитируемый пост)
Значит мне впринципе этот параметр не нужен и Я могу смело ставить NULL, главное это дескриптор потока который возвращает эта функций так?  



Это сообщение отредактировал(а) yngwie19 - 31.3.2009, 17:31
PM MAIL   Вверх
Alca
Дата 31.3.2009, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 5
Всего: 50



Цитата

Значит мне впринципе этот параметр не нужен и Я могу смело ставить NULL, главное это дескриптор потока который возвращает эта функций так?  

 smile

Добавлено через 38 секунд
Ставь NULL

Добавлено через 1 минуту и 30 секунд
Цитата

В чем выражаются эти утечки памяти.


Цитата

loss of memory that the CRT allocates


Добавлено через 2 минуты и 15 секунд
И внизу страницы глянь - там есть ссылки для тебя.


--------------------
PM WWW ICQ Skype Jabber   Вверх
yngwie19
Дата 31.3.2009, 20:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



Alca, Спасибо. Подскажи подалуйста допустим такой участок кода
Код


DWORD WINAPI Thread(LPVOID nCnt)
{

        return 0;
}

int WINAPI WinMain(......)
..........
int nPar = 10;
CreateThread(NULL,0,Thread,(LPVOID)nPar,0,NULL);
..........

Вопрос:
1) При передаче парамметра nPar в функцию Thread(), он передается как указатель ? т.е 
2) При передаче этого параметра в функции CreateThread() мы сначала его преобразовываем в указатель что-ли? или как
PM MAIL   Вверх
Alca
Дата 31.3.2009, 21:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 5
Всего: 50



Код

#include <windows.h>
#include <iostream.h>

volatile int n;

DWORD WINAPI Add(LPVOID iNum)
{
  cout << "Thread is started." << endl;
  n += (int)iNum;
  cout << "Thread is finished." << endl;

  return 0;
}

int main()
{
  int  inc = 10;
  HANDLE  hThread;
  DWORD  IDThread;

  cout << "n = " << n << endl;
  // запускаем поток Add
  hThread = CreateThread(NULL, 0, Add, (void*)inc, 0, &IDThread);
  if (hThread == NULL)
    return GetLastError();

  // ждем, пока поток Add закончит работу
  WaitForSingleObject(hThread, INFINITE);
  // закрываем дескриптор потока Add
  CloseHandle(hThread);

  cout << "n = " << n << endl;

  return 0;
}


Добавлено через 5 минут и 22 секунды
Цитата

1) При передаче парамметра nPar в функцию Thread(), он передается как указатель ? т.е 
2) При передаче этого параметра в функции CreateThread() мы сначала его преобразовываем в указатель что-ли? или как

типа да

Добавлено через 10 минут и 45 секунд
Можно еще так:
Код

hThread = CreateThread(NULL, 0, Add, &inc, 0, &IDThread);



--------------------
PM WWW ICQ Skype Jabber   Вверх
yngwie19
Дата 31.3.2009, 21:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



Цитата(Alca @  31.3.2009,  21:14 Найти цитируемый пост)
Можно еще так:

код C++
1:

hThread = CreateThread(NULL, 0, Add, &inc, 0, &IDThread);


дык здесь ты передаешь &inc как указатель типа int, а функция принимает void*. Здесь привести в void* случайно не надо?
PM MAIL   Вверх
Alca
Дата 31.3.2009, 21:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 5
Всего: 50



Скомпилилось без ворнингов.

Добавлено @ 21:36
Creating Threads

Добавлено @ 21:38
Код

HANDLE WINAPI CreateThread(
  __in_opt   LPSECURITY_ATTRIBUTES lpThreadAttributes,
  __in       SIZE_T dwStackSize,
  __in       LPTHREAD_START_ROUTINE lpStartAddress,
  __in_opt   LPVOID lpParameter,
  __in       DWORD dwCreationFlags,
  __out_opt  LPDWORD lpThreadId
);

lpParameter [in, optional] 

A pointer to a variable to be passed to the thread.


Это сообщение отредактировал(а) Alca - 31.3.2009, 21:39


--------------------
PM WWW ICQ Skype Jabber   Вверх
yngwie19
Дата 31.3.2009, 21:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



Alca, Спасибо, все же мне не очень понятно как можно переменную (в нашем случае int) привести в указателю.
PM MAIL   Вверх
Alca
Дата 31.3.2009, 21:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 5
Всего: 50



Вот так:
Код

(void*)inc


Добавлено через 30 секунд
или так:
Код

&inc



--------------------
PM WWW ICQ Skype Jabber   Вверх
Anikmar
Дата 31.3.2009, 21:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: нет
Всего: 59



[quote=Alca, 31.3.2009,  21:45, post1829523]Вот так:

(void*)inc
или так:
&inc

Эй, Alca, вы чего?

PM MAIL ICQ   Вверх
Rififi
Дата 31.3.2009, 22:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 2
Всего: 36



yngwie19, 
дык здесь ты передаешь &inc как указатель типа int, а функция принимает void*. Здесь привести в void* случайно не надо? 
не надо. указатель на void "паглащает" все другие типы указателей.
PM MAIL   Вверх
yngwie19
Дата 31.3.2009, 22:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



Цитата(Anikmar @  31.3.2009,  21:57 Найти цитируемый пост)
Эй, Alca, вы чего?
 что-то не так?
Дак что получается была переменная - стал указатель и никаких проблем?

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

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


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

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


 




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


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

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