Re: Выполнить функцию в другом потоке
От: Кодт Россия  
Дата: 24.06.04 14:49
Оценка:
Здравствуйте, Amor, Вы писали:

A>Задача:

A>Есть ряд вызовов в общем виде.
A>
A>ret = pobj->func( param1, ..., param2 ) ;
A>ret = obj.func( param1, ..., param2 ) ;
A>ret = func( param1, ..., param2 ) ;
A>


A>Нужно создать такой механизм, чтобы выполнить этот вызов в отдельном потоке. А еще лучше в конкретном потоке, который уже работает (схожие наверно задачи, если первая будет, то и до второй недалеко).


A>1. Желательно, чтобы вызов был как наименее громоздким. Т.е. что-то типа такого:

A>
A>RUN_IN_OTHER_THREAD( pobj, func, param1, ..., param2) ;
A>

A>2. Учитывать виртуальные фукцнии объектов.
A>3. Определить возможность обратного вызова с полученным результатом и возможность ожидания исполнения (т.е. возврат после того как функция выполнит свою работу).

Использовать функторы, например, boost::function + boost::bind.

typedef boost::function0<void> func_type;

struct job_type
{
  func_type func;
  HANDLE done;

  job_type() : job_done(0) {}
  job_type(func_type const& f, HANDLE d = 0) : func(f), done(d) {}
};

queue<job_type> jobs;
HANDLE there_are_jobs;
CRITICAL_SECTION job_guard;

worker_thread()
{
  while(true)
  {
    WaitForSingleObject(there_are_jobs, INFINITE);
    EnterCriticalSection(&job_guard);
    job_type job = jobs.front();
    jobs.pop();
    LeaveCriticalSection(&job_guard);
    job.func();
    if(job.done) SetEvent(job.job_done);
  }
}

void post_job(const func_type& func, HANDLE done = 0)
{
  EnterCriticalSection(&job_guard);
  jobs.push_back(job_type(func,done));
  LeaveCriticalSection(&job_guard);
}

void send_job(const func_type& func)
{
  HANDLE done = CreateEvent(NULL,true,false,NULL);
  post_job(func);
  WaitForSingleObject(done);
  CloseHandle(done);
}


(Писал ногами на коленке. Где что не так — извиняйте).
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.