C++ C++ C# C# ASP.NET Security ASP.NET Security ASM ASM Скачать Скачать Поиск Поиск Хостинг Хостинг  
  Программа для работы с LPT портом...
Язык: .NET — ©Alexey...
  "ASP.NET Atlas" – AJAX в исполнении Micro...
Язык: .NET — ©legigor@mail.ru...
  "Невытесняющая" Многопоточность...
Язык: C/C++ — ©...
  01.05.2010 — Update World C++: Сборник GPL QT исходников
  15.12.2007 — Весь сайт целиком можно загрузить по ссылкам из раздела Скачать
Хостинг:
Windows 2003, ASP.NET 2.0
бесплатный и от 80 руб./мес


   Отправить письмо
Кулабухов Артем, Беларусь




 Как лучше создать поток - статической или глобальной функцией ? / Процессы и потоки / Приложение

опубликован 30-08-2001 17:53 MSK   Click Here to See the Profile for bobo   Click Here to Email bobo  
Создаю в классе нить, в качестве начального адреса которой указываю ф-ию из другого класса (эта ф-ия статическая, иначе не компилируется) - всё нормально. Но при выполнении программы эта нить после создания прекращает своё существование... В чём может быть причина? Аргументы, которые я запихнул в CreateThread() тоже static - может в этом проблема? Но если их не сделать static, то не компилируется...
m_fox опубликован 30-08-2001 18:05 MSK     Click Here to See the Profile for m_fox  Click Here to Email m_fox     
Что за изврат использовать в классах статические функции для таких целей. Гораздо безопаснее тогда сделать глобальную функцию.
Чтобы не делать ее статической, делаешь глобальную, а ей передаешь указатель на объект, и запускаешь эту функцию на выполнение. Тогда ты получишь из нее доступ ко всем членам того объекта, которого нужно.

Хорошо бы твой пример посмотреть. Возможно ты делаешь CloseHandle, TerminateThread вне ф-ции нити. Или выходишь из функции потока.

bobo опубликован 30-08-2001 18:49 MSK     Click Here to See the Profile for bobo  Click Here to Email bobo     
Ни CloseThread(), ни TerminateThread я вообще не использую! А вот про ф-ию потока поясни попобробнее пожалуйста.

m_fox опубликован 30-08-2001 19:10 MSK     Click Here to See the Profile for m_fox  Click Here to Email m_fox     
Завтра подробно напишу. Сейчас 2 часа ночи. спать хочу.
bobo опубликован 30-08-2001 19:12 MSK     Click Here to See the Profile for bobo  Click Here to Email bobo     
Всё - заработало! Ф-ия, которую я нити передавал, с аргументом была... аргумент убрал - нить выполняется.
Flex Ferrum опубликован 31-08-2001 10:19 MSK     Click Here to See the Profile for Flex Ferrum  Click Here to Email Flex Ferrum     
m_fox:
А изврат, как ты говоришь, в том, что если ты функцию потока делаешь статическим членом класса, то тебе не надо о friend и т. п. думать. В принципе, функция потока может быть даже нестатическим членом класса (поскольку принимает один параметр, который может быть указателем на экземпляр класса). Так что, ИМХО, нет никаких причин делать функцию потока глобальной.
m_fox опубликован 31-08-2001 11:05 MSK     Click Here to See the Profile for m_fox  Click Here to Email m_fox     
Ок, допустим надо создать 5 различных функций для разных задач. И предположим, что 1-я должна работать в двух экземплярах, но с разными параметрами. В случае через static нужно будет написать 6 различных классов со всеми запусками и остановами потоков, а не просто 5 различных функций.
Я отправил статью, потом кину ссылку, посмотрите на мою идею, которой причем и пользовался.
Flex Ferrum опубликован 31-08-2001 11:19 MSK     Click Here to See the Profile for Flex Ferrum  Click Here to Email Flex Ferrum     
Зачем такие сложности? Так или иначе, с формальной точки зрения, два потока, выполняющие разные задачи ассоциируются с различными классами и имеют различне данные. По сему, так или иначе для нового типа потока нужно создавать либо новую функцию, либо новый класс. Я остановился на втором варианте, когда создается новый класс (производный от некоего базового), перегружается виртуальная функция Run, вызывающаяся из статического метода базового класса. В итоге и волки сыты, и овцы целы.
m_fox опубликован 31-08-2001 11:24 MSK     Click Here to See the Profile for m_fox  Click Here to Email m_fox     
Что значит сложности? Приходилось делать такое.
А не проще-ли сделать:
CCalcThread CalcThread1;
CCalcThread CalcThread2;
Задать просто разные значения переменным в классе и все.
Будет всего один класс.
m_fox опубликован 31-08-2001 11:37 MSK     Click Here to See the Profile for m_fox  Click Here to Email m_fox     
Вот адрес статьи:
http://athena.vvsu.ru/~kiv/threads.htm
Flex Ferrum опубликован 31-08-2001 11:52 MSK     Click Here to See the Profile for Flex Ferrum  Click Here to Email Flex Ferrum     
А можешь пояснить, какие приемущества ООП теряются при использовании статической функции потока? Помоему, как раз наоборот. Тут тебе и наследование и инкапсуляция...
m_fox опубликован 31-08-2001 12:08 MSK     Click Here to See the Profile for m_fox  Click Here to Email m_fox     
Например полиморфизм.
Попробуй сделать статическую ф-цию виртуальной.
Flex Ferrum опубликован 31-08-2001 12:20 MSK     Click Here to See the Profile for Flex Ferrum  Click Here to Email Flex Ferrum     
Согласен, статическую функцию виртуальной ты никак не сделаешь, зато без проблем можешь вызвать виртуальную функцию из статической. Например так:

int TThread::Execute(void * Param)
{
int ExitCode;
TThread * T = (TThread *)Param;
T -> Running = true;
try
{
T -> InitInstance();
T -> ExitCode = T -> Run();
T -> ExitInstance();
ExitCode = T -> ExitCode;
}
catch(std :: exception& ex)
{
LogMessage(llError,"STL exception occured in thread: %s",ex . what());
ExitCode = -1;
}
catch(...)
{
LogMessage(llError,"Unknown exception occured in thread");
ExitCode = -1;
}

T -> Running = false;
if(T -> m_AutoDelete)
delete T;

#ifdef _WIN32
return ExitCode;
#else
pthread_detach(T -> Thread);
static int RetVal = ExitCode;
pthread_exit((void *)RetVal);
#endif
}

Где Run - это виртуальная функция, отвечающая за логику потока...

m_fox опубликован 31-08-2001 12:25 MSK     Click Here to See the Profile for m_fox  Click Here to Email m_fox     
Организуй вызов:
class A
{
int m_na;
public:
A(){};
virtual Func1(){m_na++};
static Func2(){[b]Func1()[\b]};
}
Flex Ferrum опубликован 31-08-2001 12:32 MSK     Click Here to See the Profile for Flex Ferrum  Click Here to Email Flex Ferrum     
Не передергивай. Ты понимаешь, о чем я говорю. В моем случае статическая функция класса делает то-же самое, что глобальная ThreadProc в твоем.
m_fox опубликован 31-08-2001 16:11 MSK     Click Here to See the Profile for m_fox  Click Here to Email m_fox     
Вобще-то я не совсем понял твою идею. Но хотел бы посмотреть целиком или схематично.
Но в общем способ реализации на вкус производителя.
Если не лень, то вышли схемотичное решение со статической функцией, можно на email.
Flex Ferrum опубликован 31-08-2001 16:51 MSK     Click Here to See the Profile for Flex Ferrum  Click Here to Email Flex Ferrum     
Все достаточно просто.
У тебя есть базовый класс для всех ниток:
class TThread
{
virtual int Run() = 0;
static int Execute();
public:
TThread() {;}
~TThread() {;}
void Start();
};

void TThread :: Start()
{
Thread = CreateThread(NULL,0,(TThreadFunct)TThread :: Execute,this,0,NULL);
}

int TThread :: Execute(void * _T)
{
TThread * T = (TThread *)T;
return T -> Run();
}

В производных классах перегружаешь метод Run. И все. После чего пишешь:
TMyThread Thread;
Thread . Start();

В принципе, то-же самое, что и у тебя, только твоя глобальная ThreadProc сделана статической. Согласись, этот вариант чуть больше отвечает концепциям ООП.

Flex Ferrum опубликован 31-08-2001 17:01 MSK     Click Here to See the Profile for Flex Ferrum  Click Here to Email Flex Ferrum     
В догонку - естественно, Run должен быть protected.
m_fox опубликован 31-08-2001 17:40 MSK     Click Here to See the Profile for m_fox  Click Here to Email m_fox     
Тепрь понял. Я еще сам это покручу.
Но ты знаешь, когда мы решали эту проблему, то так через static мы не догнали. Мы статик функцию передовали в качестве параметра и у нас фигня шла, как сам понимаешь.
Flex Ferrum опубликован 31-08-2001 17:49 MSK     Click Here to See the Profile for Flex Ferrum  Click Here to Email Flex Ferrum     
Фишка, на самом деле, в том, что тут можно напрямую нестатический метод передавать. Ведь каждый нестатический метод получаеи в качестве неявного параметра this (указатель на экземпляр), а функция потока получает на входе всего один параметр, и тот void * , т. е. может быть чем угодно. Так что, при большом желании, можно и без static обойтись.
m_fox опубликован 31-08-2001 18:04 MSK     Click Here to See the Profile for m_fox  Click Here to Email m_fox     
Ты в какой области работаешь?
Я последние пару лет занимался обработкой изображений.
Flex Ferrum опубликован 31-08-2001 23:43 MSK     Click Here to See the Profile for Flex Ferrum  Click Here to Email Flex Ferrum     
В настоящее время работаю в области веб- и системного программирования, но, пока учился, занимался цифровой фотограмметрией и смежными с ней областями.