Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Дао Потоков

8.6K
04 января 2006 года
DeadLOL
22 / / 27.09.2005
Нашел в сях++ две ф-ции создания потоков
_beginthread()
&
CreateThread()

Хочу услышать мнения бывалых по поводу этих ф-ций
когда какую использовать.... В чем отличия... и так далее...
3
05 января 2006 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by DeadLOL
Нашел в сях++ две ф-ции создания потоков
_beginthread()
&
CreateThread()

Хочу услышать мнения бывалых по поводу этих ф-ций
когда какую использовать.... В чем отличия... и так далее...



Обе функции не имеют отношения к оригинальному С++.
CreateThread - это функция Win32 API,
_beginthread - это функция MS расширения C++.

Если ты используешь в коде что-нибудь из CRT (а ведь однозначно используешь), то лучше применять _beginthread.

Цитата:

A thread in an executable that calls the C run-time library (CRT) should use the _beginthread and _endthread functions for thread management rather than CreateThread and ExitThread; this requires the use of the multi-threaded version of the CRT. It is safe to call CreateThread and ExitThread from a thread in a DLL that links to the static CRT as long as the thread does not call the DisableThreadLibraryCalls function.

2.4K
05 января 2006 года
dinasok51
219 / / 12.11.2005
ИМХО лучше _beginthreadex(), кот. позволяет более тонко управлять запуском потоков.

Читал когда-то статью Рихтера, где анализировался код СreateThread() и рекомендовалось ее не использовать

Не зря MS разработали _beginthread() и _beginthreadex().
398
06 января 2006 года
Alexandoros
630 / / 21.10.2005
По большому счету разница между ними в том, что при использовании CRT в мультипотоковых приложениях, среда с++ выделяет память для некоторых внутренних переменных. Так вот _endthread(), которая вызывается автоматом - освобождает память, а тред созданый CreateThread не вызывает _endthread(). Поэтому наблюдается мелкие лики мемори при юзаньи CRT и CreateThread. Вот кажись и вся разница :)
12K
22 января 2006 года
Stefan
6 / / 05.08.2005
А можно ли в качестве точки старта нового потока указать функцию-член класса? Естественно если поток создается объектом этого класса.
Хотелось бы из этого потока обращаться к данным класса, неохото засовывать их все в структуру и передовать в поток еще и указатель на нее.

Хотя в любом случае придется синхронизировать обращения потоков к этим данным X)-
2.4K
22 января 2006 года
dinasok51
219 / / 12.11.2005
Можно.
Функция д.б. unsigned __stdcall, а общие данные д.б. volatile
2.4K
23 января 2006 года
dinasok51
219 / / 12.11.2005
Цитата:
Originally posted by dinasok51
Можно.
Функция д.б. unsigned __stdcall, а общие данные д.б. volatile



Забыл добавить:
unsigned __stdcall - это если запускаешь с пом. _beginthreadex(). в других - иначе, см. описание

3
23 января 2006 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by dinasok51
Забыл добавить:
unsigned __stdcall - это если запускаешь с пом. _beginthreadex(). в других - иначе, см. описание


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

398
23 января 2006 года
Alexandoros
630 / / 21.10.2005
Цитата:
Originally posted by Stefan
А можно ли в качестве точки старта нового потока указать функцию-член класса?


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

Код:
CMyClass
{
public:
   void Potok();
}

DWORD Potok(void *obj)
{
    reinterpret_cast<CMyClass *>(obj)->Potok();
    return 0;
}

int WinMain(...)
{
   DWORD id;
   CMyClass cl;

   CreateThread(0, 0, ::Potok, &cl, 0, &id);
}
3
23 января 2006 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by Alexandoros
Код:
CMyClass
{
public:
   void Potok();
}

DWORD Potok(void *obj)
{
    reinterpret_cast<CMyClass *>(obj)->Potok();
    return 0;
}

int WinMain(...)
{
   DWORD id;
   CMyClass cl;

   CreateThread(0, 0, ::Potok, &cl, 0, &id);
}


Только логичнее сделать функцию DWORD Potok(void *obj) статическим методом всё того же класса, а пускать поток лучше с помощью _beginthread, а не CreateThread.

12K
27 января 2006 года
Stefan
6 / / 05.08.2005
А еще интересно как лучше их потом убивать? Из основного потока имеется ввиду.
3
27 января 2006 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by Stefan
А еще интересно как лучше их потом убивать? Из основного потока имеется ввиду.


Убивать никого нельзя, это смертный грех.
Потоку надо дать понять, что он больше никому не нужен, пусть покончит жизнь суицидом.
Говоря нормально, из основного потока выставляется некоторый флаг, в дочернем потоке этот флаг переодически проверяется, и как только флаг будет выставлен поток сам корректно завершается.
А убивать поток - это плохая практика, ты ведь в штатном режиме не терминируешь программы.

2.4K
27 января 2006 года
dinasok51
219 / / 12.11.2005
Цитата:
Originally posted by Stefan
А еще интересно как лучше их потом убивать? Из основного потока имеется ввиду.


 
Код:
BOOL TerminateThread(
  HANDLE hThread,    // handle to thread
  DWORD dwExitCode   // exit code
);


При этом нужно быть осторожным-все выделенные и занятые в thread ресурсы остаются занятыми.
12K
27 января 2006 года
Stefan
6 / / 05.08.2005
Цитата:
Originally posted by Green
Говоря нормально, из основного потока выставляется некоторый флаг, в дочернем потоке этот флаг переодически проверяется, и как только флаг будет выставлен поток сам корректно завершается.



У меня при этом возникла некоторая проблема. Хотя наверно это уже оффтоп, вобщем у меня там цикл:

 
Код:
while(flag && accept(...))
    {
      ...
    }

вобщем прога работает с сокетом и является сервером.
Так вот когда к серваку никто не конектится, то accept видимо не возвращает управления и поток не может проверить переменную flag второй раз :)

К стати, если кому то интересно поток завершается вызовом функции void _endthread(). Кажется она вызывается автоматически при выполнении return.
2.4K
27 января 2006 года
dinasok51
219 / / 12.11.2005
Цитата:
Originally posted by Stefan
У меня при этом возникла некоторая проблема. Хотя наверно это уже оффтоп, вобщем у меня там цикл:
 
Код:
while(flag && accept(...))
    {
      ...
    }

вобщем прога работает с сокетом и является сервером.
Так вот когда к серваку никто не конектится, то accept видимо не возвращает управления и поток не может проверить переменную flag второй раз :)

К стати, если кому то интересно поток завершается вызовом функции void _endthread(). Кажется она вызывается автоматически при выполнении return.


Напр. пошли сам себе сообщение

12K
28 января 2006 года
Stefan
6 / / 05.08.2005
Цитата:
Originally posted by dinasok51
Напр. пошли сам себе сообщение



В смысле создать еще один сокет и с него законектится к самому себе? Както геморно получается. А другого пути нет?

3
30 января 2006 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by Stefan
А другого пути нет?


Использовать асинхронные сокеты.

1
31 января 2006 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by Green
Использовать асинхронные сокеты.


А так же не использовать в качестве условия accept(...) - для работы с сокетом в потоке проще обрабатывать события сокета.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог