Многопоточность в с ++ - PullRequest
       5

Многопоточность в с ++

3 голосов
/ 22 января 2011

Я хочу запустить одну функцию с разными параметрами в разных потоках:

int threads = 3;
int par1[] = {1, 2, 3};
int par2[] = {4, 5, 6};
for (int i=0; i<threads; i++){
  //new_thread function(par1[i], par2[i]);
}

Я ничего не знаю о темах. Я пытался сделать что-то Windows API (не могу использовать другие библиотеки), но это не работает. Как мне это реализовать? А можно ли запустить неизвестное количество потоков во время программирования (динамически создавая потоки)?

Ответы [ 6 ]

11 голосов
/ 22 января 2011

Один пример для Windows,

#include <Windows.h>

struct thread_data
{
 int m_id;
 thread_data(int id) : m_id(id) {}
};
DWORD WINAPI thread_func(LPVOID lpParameter)
{
 thread_data *td = (thread_data*)lpParameter;
 cout << "thread with id = " << td->m_id << endl;
 return 0;
}
int main()
{
 for (int i=0; i< 10; i++)
 {
  CreateThread(NULL, 0, thread_func, new thread_data(i) , 0, 0);
 }
}

В этом примере каждый поток получает разные данные, а именно типа thread_data, которые передаются в качестве аргумента функции потока thread_func(). * 1006.*

Прочтите это, чтобы узнать, как создать поток в Windows:

http://msdn.microsoft.com/en-us/library/ms682516(VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms682453(v=vs.85).aspx


Также вам может понравиться это предложение:

Улучшенный дизайн: определите класс многократного использования!

5 голосов
/ 22 января 2011

Я ничего не знаю о темах.

Это проблема. Нитки - это одна из областей, где эксперименты без хотя бы некоторого теоретического фона обычно заканчиваются катастрофой. Существует так много всего, что может пойти не так с многопоточностью, но это происходит не так часто, намного позже.

Я бы предложил либо получить книгу о многопоточности, либо прочитать несколько статей в Интернете перед началом работы.

Если вы заинтересованы в использовании многопоточности для повышения эффективности, тогда Столбец Херба Саттера может быть для вас. И еще есть отличное Введение в параллельные вычисления Блеза Барни.

3 голосов
/ 22 января 2011

Вам нужно сделать пару вещей, чтобы заставить это работать.Прежде всего, функция потока Windows принимает эту сигнатуру:

DWORD WINAPI ThreadFunction(LPVOID args)

Процедура запуска потока - это функция:

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
);

Обратите внимание, что способ передачи аргументов в функцию потока - черезLPVOID.Это означает, что вам нужно создать структуру для хранения ваших par1 и par2.Затем вы передадите указатель на эту структуру и извлечете содержимое в своей подпрограмме потока.

1 голос
/ 22 января 2011

Могу ли я предложить использовать boost :: thread_group ?

boost::thread_group g;
int threads = 3;
int par1[] = {1, 2, 3};
int par2[] = {4, 5, 6};
for (int i=0; i<threads; i++){
  g.create_thread(/*function*/);
  //new_thread function(par1[i], par2[i]);
}
g.join_all();
1 голос
/ 22 января 2011

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

В вашем примере простой (и слегка наивный - обычно вы не говорите явно число потоков, вы говорите количество рабочих единиц):

int threads = 3;
int par1[] = {1, 2, 3};
int par2[] = {4, 5, 6};
#pragma omp parallel for
for (int i=0; i<threads; i++){
  function(par1[i], par2[i]);
}

С соответствующей опцией, переданной компилятору для включения OpenMP. Без этой опции он все еще компилируется и запускается как последовательная программа.

0 голосов
/ 22 января 2011

Вы создаете тему в Windows, вызывая CreateThread . Вот пример здесь .

Да, вы можете динамически создавать темы.

Теперь, когда вызывается ваша «функция потока» (что означает, что поток запущен), вы используете переданный параметр, который вы указали при вызове CreateThread.
В "thread-function" это "LPVOID lpParam". Вы должны привести его к своему типу. Если вам нужно передать два объекта в поток, то создайте свой собственный struct / class с соответствующими членами и передайте его экземпляр при вызове CreateThread, чтобы вы могли использовать его позже. Очень прямолинейно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...