Форум программистов CodeGuru
25 Сентябрь 2018, 21:41:43 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.

Войти
Новости:
 
   Начало   Помощь Войти Регистрация  
Страниц: [1]   Вниз
  Печать  
Автор Тема: createthread  (Прочитано 28109 раз)
0 Пользователей и 1 Гость смотрят эту тему.
NehemiaN
Интересующийся
**
Офлайн Офлайн

Сообщений: 12


Просмотр профиля
« : 21 Октябрь 2010, 20:55:57 »

Дяди и Тети помогите разобраться с потоками: Создать несколько потоков (количество можно вводить с клавиатуры). Вывести их в обратном порядке. Потоки создаются с помощью оператора createthread.
Записан
3V
Администратор
Ветеран
*****
Офлайн Офлайн

Сообщений: 1347



Просмотр профиля WWW
« Ответ #1 : 21 Октябрь 2010, 23:53:18 »

А в чем вопрос то ?

Вывести их в обратном порядке.

Кого вывести ?

Потоки создаются с помощью оператора createthread.

Это в каком языке есть оператор createthread для создания потоков ?
Если следовать банальной логике, то размещение темы в разделе "Программирование под Windows > API, базовые сервисы и общие вопросы", как бэ намекает, что Вам надо в приложении под Windows создавать потоки при помощи API-функции CreateThread. Хотя... может не это совсем надо ?

По поводу CreateThread (на всякий случай).
Прототип ее:

Код:
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
);

Подробнее: CreateThread в MSDN.
Записан

NehemiaN
Интересующийся
**
Офлайн Офлайн

Сообщений: 12


Просмотр профиля
« Ответ #2 : 22 Октябрь 2010, 12:01:17 »

Ды, в делфе мне надо, но спасибо, хоть сделать не сделал, за то хоть с параметрами разобрался. А задачку не знаете как делать ???)))
Записан
3V
Администратор
Ветеран
*****
Офлайн Офлайн

Сообщений: 1347



Просмотр профиля WWW
« Ответ #3 : 22 Октябрь 2010, 23:31:08 »

А задачку не знаете как делать ???)))

Ну не совсем понятно что означает "Вывести их в обратном порядке".

Ну вот создали нужное количество потоков. А что дальше ?
Тут тоже вопросы. Поток сам по себе как бы смысла не имеет. Точнее, при создании потока в качестве lpStartAddress указывается точка входа в функцию. Т.е. грубо говоря, какая либо функция запускается в потоке. А эта функция должна что-то делать. Как только функция завершится (произойдет выход из нее), то поток тоже завершится.
Что должны делать эти функции ?
К слову, в функции можно крутить цикл обработки сообщений. И при первом вызове GetMessage или PeekMessage будет создана очередь сообщений для этого потока.

В общем, совсем не понятно, что в итоге надо получить.
Записан

NehemiaN
Интересующийся
**
Офлайн Офлайн

Сообщений: 12


Просмотр профиля
« Ответ #4 : 23 Октябрь 2010, 21:07:08 »

На сколько я понял, то надо чтобы мы создали потоки createthread(...) которые обращаются к функции, которая не важно что делает, хоть единицу прибавляет. Потом мы берем какую-нибудь переменную, пихаем ее в поток и выводной результат будет наверное в обратном порядке. Мне кажется так... Я наваял программку... доделаю выложу))) Просто хотел спросить Вот там есть параметры createthread(nil,0,@sed,@n,0,ID). Вот Sed - это наша процедура, да ???  @n - это указатель на переменную ??? ID - имя потока ???   Вот куда запишется результат процедуры Sed, И как его достать если она запишется по адресу @n ???
Записан
3V
Администратор
Ветеран
*****
Офлайн Офлайн

Сообщений: 1347



Просмотр профиля WWW
« Ответ #5 : 24 Октябрь 2010, 09:03:55 »

Если я все правильно понимаю, то в Delphi можно это так сделать:

Код:
procedure ThreadFunc(P: Pointer); stdcall;
var
    { тут_переменные }
begin
    { код_функции }
end;

{ ... }
{ вызов CreateThread }
procedure BeginThread()
var
    nThreadID: DWORD;
    hThread: THandle;
begin

hThread := CreateThread(nil, 0, @ThreadFunc, nil, 0, nThreadID);

if hThread = 0 then
    { не удалось запустить поток ... что-то делаем для обработки ошибки }

end;


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

@n - это указатель на переменную ??? ID - имя потока ???   Вот куда запишется результат процедуры Sed, И как его достать если она запишется по адресу @n ???

Ну да, @n - это любой указатель и он передастся параметром в функцию @sed. Чтобы одновременно и передать параметр в функцию, исполняемую в потоке, и получить результат, нужно создать структуру с полями, в которой некоторые поля будут параметрами, а одно будет отведено под результат исполнения, например. Адрес этой структуры передать в качестве @n. В sed использовать поля этой структуры как надо, а перед выходом записать в эту структуру что надо (например, результат). Но... нужно, чтобы структура существовала все время, пока выполняется функция в потоке. Для этого можно использовать синхронизацию по дескриптору / дескрипторам, например, функции WaitForSingleObject, WaitForMultipleObjects.
« Последнее редактирование: 24 Октябрь 2010, 09:12:31 от 3V » Записан

NehemiaN
Интересующийся
**
Офлайн Офлайн

Сообщений: 12


Просмотр профиля
« Ответ #6 : 24 Октябрь 2010, 18:09:07 »

спасибки, щас буду разбираться
Записан
NehemiaN
Интересующийся
**
Офлайн Офлайн

Сообщений: 12


Просмотр профиля
« Ответ #7 : 07 Ноябрь 2010, 00:36:16 »

Вот как-то так, кривая да, но как умею(((
Код:
program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Windows;

var n,t,Ed,RE:integer;
Thred:array[0..255] of Thandle;
ID:Dword;
MM:Thandle;

procedure Sed;
var f,i:integer;
 begin
  for i:=0 to 4 do
  begin
    f:=f+5+ed;
    writeln(f);
  end;
 end;

begin
write('Kol-vo Potokov ');
n:=strtoint(paramstr(1));
writeln(n);
for ed:=1 to n do begin
Thred[ed]:=createthread(nil,0,@Sed,nil,CREATE_SUSPENDED,ID);
end;
readln;
  for ed:=n downto 1 do
  begin
  ResumeThread(Thred[ed]);
   Thred[ed]:=createthread(nil,0,@Sed,nil,0,ID);
  waitforsingleobject(MM,2000);
  end;


  readln;
end.
 
Записан
NehemiaN
Интересующийся
**
Офлайн Офлайн

Сообщений: 12


Просмотр профиля
« Ответ #8 : 07 Ноябрь 2010, 00:36:43 »

препод сказ сделать  mutex помогите
Записан
3V
Администратор
Ветеран
*****
Офлайн Офлайн

Сообщений: 1347



Просмотр профиля WWW
« Ответ #9 : 07 Ноябрь 2010, 11:19:39 »

препод сказ сделать  mutex помогите

Где и для чего mutex нужен ? Непонятно.
mutex - это объект синхронизации. Обычно применяют для синхронизации доступа к данным.

В приведенном коде, кстати, во втором цикле (насколько я понимаю замысел) не надо еще создавать потоки и waitforsingleobject непонятно для чего делается (что за переменная MM и для чего вообще waitforsingleobject нужен). Если нужно ждать завершения всех потоков, то надо использовать WaitForMultipleObjects (туда передается массив дескрипторов).
Записан

NehemiaN
Интересующийся
**
Офлайн Офлайн

Сообщений: 12


Просмотр профиля
« Ответ #10 : 13 Ноябрь 2010, 11:52:00 »

Код:
program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Windows;

var n,Ed:integer;
Thred:array[0..255] of Thandle;
ID:Dword;

procedure Sed;
 begin
   writeln(ed);
 end;

begin
write('Kol-vo Potokov ');
n:=strtoint(paramstr(1));
writeln(n);
   for ed:=1 to n do
     begin
       Thred[ed]:=createthread(nil,0,@Sed,pointer(ed),0,ID);
       ResumeThread(Thred[ed]);
       waitforsingleobject(Thred[ed],1000);
     end;
readln;
end.

Вот еще косяк)))) Вот сейчас потоки выводятся в нормальном порядке. А с помощью Mutex надо сделать так чтобы потоки выводились в обратном порядке. Если я правильно понимаю, надо чтобы мы создавли какие-то N потоков в нормальном порядке. Потом создавалось бы столько же mutex-ов.потом последнии mutex открывается и выводит последнии поток, потом предпоследнии и так до первого. Так как мьютекс сделать ???))))


 Помогите Помогите
« Последнее редактирование: 13 Ноябрь 2010, 11:54:34 от NehemiaN » Записан
NehemiaN
Интересующийся
**
Офлайн Офлайн

Сообщений: 12


Просмотр профиля
« Ответ #11 : 15 Ноябрь 2010, 09:38:58 »

Ну Помогите, Люди
Записан
3V
Администратор
Ветеран
*****
Офлайн Офлайн

Сообщений: 1347



Просмотр профиля WWW
« Ответ #12 : 16 Ноябрь 2010, 00:26:38 »

В делфи я не очень, и как там классы потоков реализованы - точно не знаю.
Судя по тому, что надо делать ResumeThread, не указав при создании потока флаг CREATE_SUSPENDED (основываясь на вашем коде), что-то там наверчено дополнительно. Не известно также, есть ли синхронизация в классе потока при запуске (в том же MFC, например, при создании объекта класса потока, создаются 2 дополнительных мьютекса именно для синхронизации его при запуске).

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

Код:
function Sed(ed: Pointer): Integer
begin
...

Возможно, будет работать что-то типа этого:

Код:
program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Windows;

var n,Ed:integer;
Thred:array[0..255] of Thandle;
Mutexes:array[0..255] of THandle;
ID:Dword;

function Sed(ed: Pointer): Integer
begin
   waitforsingleobject(Mutexes[ed],INFINITE);
   writeln(ed);
end;

begin
write('Kol-vo Potokov ');
n:=strtoint(paramstr(1));
writeln(n);
   for ed:=1 to n do
     begin
       Mutexes[ed] := CreateMutex(NIL, TRUE, NIL);
       Thred[ed]:=createthread(nil,0,@Sed,pointer(ed),0,ID);
       ResumeThread(Thred[ed]);
     end;

   for ed:=n downto n do
     begin
       ReleaseMutex(Mutexes[ed]);
       waitforsingleobject(Thred[ed],INFINITE);
     end;

readln;
end.

Опять же, обратите внимание на то, что в этом случае будет определенный оверхед из-за ожидания завершения каждого потока по отдельности. По идее, надо вообще не мьютексами, а сигналами пользоваться, чтобы каждый поток сразу же после вывода, еще до завершения, сигналил основному потоку, чтобы тот запускал следующий поток (в смысле не запускал даже, а дергал соответствующий event). Кстати, вот вам еще идея. Можно в самой функции потока дергать соответствующий объект синхронизации следующего потока.
« Последнее редактирование: 16 Ноябрь 2010, 00:31:00 от 3V » Записан

NehemiaN
Интересующийся
**
Офлайн Офлайн

Сообщений: 12


Просмотр профиля
« Ответ #13 : 13 Декабрь 2010, 20:30:22 »

Всем Спасибо.



Вот рабочии Вариант:
Код:
program Project2;

{$APPTYPE CONSOLE}

uses
  Windows,
  SysUtils;

{const
  N = 10; }

var
  Handles: array [0..255] of THandle;

procedure ThreadProc ;
var Index: Integer;
begin
  WaitForSingleObject(Handles[Index+1],INFINITE);
  Writeln(Index);
end;

var
  i,n: Integer;
  ThreadId: Cardinal;
begin
 n:=strtoint(paramstr(1));
  Handles[N]:=CreateSemaphore(nil,0,1,nil);
  for i:=0 to N-1 do Handles[i]:=createThread(nil,0,@ThreadProc,Pointer(i),0,ThreadId);
  ReleaseSemaphore(Handles[N],1,nil);
  WaitForMultipleObjects(N-1,@Handles,True,INFINITE);
  readln;
end.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!