PDA

Просмотр полной версии : [Delphi] Переключение потоков между собой


_PARAZIT_
20.12.2009, 01:37
Товарищи подскажите как можно переключать патоки между собой: например есть паток T1 он в Memo все время пишет букву `A`, есть поток T2 он в Memo все время пишет букву `B`..... необходимо реализовать так что бы при нажатии на одну кнопку работал поток T1, а при нажатии на другую кнопку - T2..... как это сделать? необходимо ли уничтожать поток T1 перед созданием потока T2 или нет? создавать их когда, одновременно или как?

0ldbi4
20.12.2009, 01:50
Ну потоковые проги не писал, но ядумаю что пускаешь T1 он выполняется отдаешь квант и не принимаешь его пока не выполнится второй, ну флаг какойнить замути)

_PARAZIT_
20.12.2009, 02:12
у кого еще мысли есть?

_s1r1us_
20.12.2009, 02:19
Товарищи подскажите как можно переключать патоки между собой: например есть паток T1 он в Memo все время пишет букву `A`, есть поток T2 он в Memo все время пишет букву `B`

Попробуй реализовать это, и я думаю сам ответишь на свои вопросы=))

_PARAZIT_
20.12.2009, 02:33
уже реализовано....... я просто думаю, по нажатию первой кнопки делать T1.Suspend T2.resume, а по второй кнопке наоборот, но это как то тупо..... может ктонибудь знает нормальный способ?

_s1r1us_
20.12.2009, 02:37
ты каждый поток в ручную создаешь?(T1,T2,T3,...,Tn)? тупо ппц

_PARAZIT_
20.12.2009, 02:43
их всего два или три......
а как надо?
и переключать все же их как?

AquaKlaster
20.12.2009, 02:44
ты каждый поток в ручную создаешь?(T1,T2,T3,...,Tn)? тупо ппц
Согласен, циклом легче в n раз=)

Algol
20.12.2009, 02:48
уже реализовано....... я просто думаю, по нажатию первой кнопки делать T1.Suspend T2.resume, а по второй кнопке наоборот, но это как то тупо..... может ктонибудь знает нормальный способ?
как то тупо - это довольно точная формулировка :D

А можно поинтересоваться, зачем нужно "переключаться между пАтоками" ?
Обычно пОтоки создаются для того, что бы они работали паралельно :)

_PARAZIT_
20.12.2009, 02:50
...задание такое.
ну может ктонибудь по существу чтонибудь скажет?

Algol
20.12.2009, 02:53
Что бы кто-то что-то сказал по существу, нужно по существу задавать вопрос.

_PARAZIT_
20.12.2009, 03:02
Что бы кто-то что-то сказал по существу, нужно по существу задавать вопрос.


unit TruncThread;

interface

uses Classes;

type
TTruncThread = class(TThread)
private
{ Private declarations }
Count_:integer;
Update_Line:integer;
protected
procedure Execute; override;
procedure UpdateCaption;
end;

implementation

uses MainServ;

procedure TTruncThread.UpdateCaption;
begin
Form1.Memo1.Lines.Add(Spisok[Update_Line]);
end;

procedure TTruncThread.Execute;
var CurrentCount, i:integer;
Temp_str:string;
begin
Count_:=1;
while not(Terminated) do begin
CurrentCount:=spisok.Count;
if CurrentCount>Count_ then begin
for i:=Count_ to CurrentCount do begin
if length(Spisok.Strings[i-1])>80 then begin
Temp_str:=Spisok.Strings[i-1];
SetLength(Temp_str, 80);
Spisok.Strings[i-1]:=Temp_str;
end;
Update_Line:=i-1;
Synchronize(UpdateCaption);
end;
Count_:=CurrentCount;
end;
end;
end;

end.


вот есть пОток, необходима написать еще один поток, что бы этот являлся ему предком, в нем нужно рализовать что бы Spisok.Strings был в верхнем регистре, и что бы была возможность переключать потоки в основной форме программы... ктонибудь поможет?

Markus_13
20.12.2009, 03:53
вот есть пОток, необходима написать еще один поток, что бы этот являлся ему предком, в нем нужно рализовать что бы Spisok.Strings был в верхнем регистре, и что бы была возможность переключать потоки в основной форме программы... ктонибудь поможет?
нах это "чтобы этот являлся ему предком"???
вот код переводит строки в Spisok.Strings в верхний регистр:
function strcUP(s:string):string;var r:string;k:byte;begin r:=s;for k:=1 to length(r)do begin
if r[k]='a'then r[k]:='A';if r[k]='b'then r[k]:='B';if r[k]='c'then r[k]:='C';if r[k]='d'then r[k]:='D';
if r[k]='e'then r[k]:='E';if r[k]='f'then r[k]:='F';if r[k]='g'then r[k]:='G';if r[k]='h'then r[k]:='H';
if r[k]='i'then r[k]:='I';if r[k]='j'then r[k]:='J';if r[k]='k'then r[k]:='K';if r[k]='l'then r[k]:='L';
if r[k]='m'then r[k]:='M';if r[k]='n'then r[k]:='N';if r[k]='o'then r[k]:='O';if r[k]='p'then r[k]:='P';
if r[k]='q'then r[k]:='Q';if r[k]='r'then r[k]:='R';if r[k]='s'then r[k]:='S';if r[k]='t'then r[k]:='T';
if r[k]='u'then r[k]:='U';if r[k]='v'then r[k]:='V';if r[k]='w'then r[k]:='W';if r[k]='x'then r[k]:='X';
if r[k]='y'then r[k]:='Y';if r[k]='z'then r[k]:='Z';if r[k]='а'then r[k]:='А';if r[k]='б'then r[k]:='Б';
if r[k]='в'then r[k]:='В';if r[k]='г'then r[k]:='Г';if r[k]='д'then r[k]:='Д';if r[k]='е'then r[k]:='Е';
if r[k]='ё'then r[k]:='Ё';if r[k]='ж'then r[k]:='Ж';if r[k]='з'then r[k]:='З';if r[k]='и'then r[k]:='И';
if r[k]='й'then r[k]:='Й';if r[k]='к'then r[k]:='К';if r[k]='л'then r[k]:='Л';if r[k]='м'then r[k]:='М';
if r[k]='н'then r[k]:='Н';if r[k]='о'then r[k]:='О';if r[k]='п'then r[k]:='П';if r[k]='р'then r[k]:='Р';
if r[k]='с'then r[k]:='С';if r[k]='т'then r[k]:='Т';if r[k]='у'then r[k]:='У';if r[k]='ф'then r[k]:='Ф';
if r[k]='х'then r[k]:='Х';if r[k]='ц'then r[k]:='Ц';if r[k]='ч'then r[k]:='Ч';if r[k]='ш'then r[k]:='Ш';
if r[k]='щ'then r[k]:='Щ';if r[k]='ъ'then r[k]:='Ъ';if r[k]='ы'then r[k]:='Ы';if r[k]='ь'then r[k]:='Ь';
if r[k]='э'then r[k]:='Э';if r[k]='ю'then r[k]:='Ю';if r[k]='я'then r[k]:='Я';end;result:=r;end;

procedure TTruncThread2.Execute;
var CurrentCount, i:integer;
begin
while not(Terminated) do begin
CurrentCount:=spisok.Count;
for i:=0 to CurrentCount-1 do
Spisok.Strings[i]:=strcUP(Spisok.Strings[i]);
end;
end;

W!z@rD
20.12.2009, 08:53
StrToLower/Upper

не понял, зачем такой код лопатить?!?! о_О

Касательно потоков. Для чего они нужны? Для параллельной работы.

И вот, почитай на досуге, про потоки http://forum.vingrad.ru/forum/topic-60076.html

_PARAZIT_
20.12.2009, 17:05
как сделать верхний регистр я знаю.... и как наследовать я знаю.... не надо задавать вопросы на счет тупости, задание есть задание, я незадаю лишних вопросов.
субственно суть вопроса - как переключать два потока между собой?

W!z@rD
20.12.2009, 20:34
как сделать верхний регистр я знаю.... и как наследовать я знаю.... не надо задавать вопросы на счет тупости, задание есть задание, я незадаю лишних вопросов.
субственно суть вопроса - как переключать два потока между собой?

шиздец, ссылку кому дал?

скажи сразу, не хочу вкуривать, дайте тупо работающий код.

intNet
20.12.2009, 20:56
Потоки могут работать независимо друг от друга.
Создаёшь поток через CreateThread/BeginThread, ссылающийся на нужную тебе функцию, и никаких TThread не надо, да и работать всё будет стабильнее.

...
procedure Memo1Add();
begin
while true do
Form1.Memo1.Lines.Append('a');
ExitThread(0);
end;

procedure Memo2Add();
begin
while true do
Form1.Memo2.Lines.Append('b');
ExitThread(0);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
CloseHandle(CreateThread(nil, 0, @Memo1Add, nil, 0, dwThreadID));
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
CloseHandle(CreateThread(nil, 0, @Memo2Add, nil, 0, dwThreadID));
end;

end.

_PARAZIT_
21.12.2009, 01:46
intNet спосибо большое конечно, но тут к сожалению вопрос стоит остро и зависит он не от меня, так что реализация на WinAPI не пойдет.....
а на счет вкуривания зря так издеваетесь:
http://www.rsdn.ru/forum/delphi/3358361.flat.aspx
http://forum.vingrad.ru/forum/topic-60076.html
http://digs.alfaspace.net/topics/8
http://www.delphisources.ru/pages/faq/base/threads_development.html
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1370
..................
.....нужен ответ по теме, а не философия

Pr0mo
21.12.2009, 02:20
Товарищи подскажите как можно переключать патоки между собой: например есть паток T1 он в Memo все время пишет букву `A`, есть поток T2 он в Memo все время пишет букву `B`..... необходимо реализовать так что бы при нажатии на одну кнопку работал поток T1, а при нажатии на другую кнопку - T2..... как это сделать? необходимо ли уничтожать поток T1 перед созданием потока T2 или нет? создавать их когда, одновременно или как?

Вообще, на сколько я помню потокам можно задавать приоритеты. Соответсвенно, если у потока T1 приоритет 0, а у другого (T2) отличный от нуля, то процессорное время будет затрачиваться именно на поток T2.

zeppe1in
21.12.2009, 02:30
я просто думаю, по нажатию первой кнопки делать T1.Suspend T2.resume, а по второй кнопке наоборот, но это как то тупо..... может ктонибудь знает нормальный способ?
Почему тупо? вроде самое то.

Markus_13
21.12.2009, 02:39
_PARAZIT_, сам незнаешь чего хочешь =\

slesh
21.12.2009, 10:31
делай 1 поток который из глобальной переменной будет брать букву которую писать.
Нажал на одну кнопку, в эту переменную записалась нужная буква
Нажал на другую кнопку, в ней записалась другая буква.

_PARAZIT_
21.12.2009, 14:36
Спасибо всем ответившим.... доверимся опыту zeppe1in и сделаем как было написано выше, добавив небольшой класс управления потоками с реализацией необходимых методов добавления потоков и их переключения.

zeppe1in
21.12.2009, 14:55
если что, то я не виноват)

_PARAZIT_
24.12.2009, 01:14
блин..... дополнительный вопросик возник: как правильно синхронизировать через критическую секцию? у меня к серверу несколько клиентов могут слать одновременно данные, и необходимо сформировать общий список, так сказать, и сихронизировать добавление данных в него с помощью критической секции...

sn0w
24.12.2009, 19:45
далеко не лучший вариант, но просто тока что докодил в своих целях.


DWORD g_last_time;
CRITICAL_SECTION timesec;
//////////////////////////////////////////////////////////////////////////
DWORD WINAPI TimeCheckThread(LPVOID lp)
{

while(TRUE){
EnterCriticalSection(&timesec);
if(GetTickCount()-g_last_time > 200){ // signal lost more than 200ms
printf("SIGNAL LOST\r");
}else{
printf("SIGNAL GOOD\r");
}
LeaveCriticalSection(&timesec);
Sleep(1);
}

return 0;
}

//////////////////////////////////////////////////////////////////////////
void CaptureLoop(SOCKET ssock)
{
char *pdata = (char*)malloc(65536);
int isize = 0;
DWORD tid;

printf("waiting for broadcast signals...\n");

InitializeCriticalSection(&timesec);

g_last_time = GetTickCount();
CreateThread(0,0,TimeCheckThread,0,0,&tid);

while(!_kbhit()){

isize = recvfrom(ssock, pdata, 65536, 0, 0, 0);

if(isize > 0){
// analyse the packet
PACKET *ppack = (PPACKET)pdata;

if(ppack->iphdr.ip_protocol == IPPROTO_UDP)
if(ppack->udphdr.dst_port == htons(33333))
if(memcmp((((LPBYTE)ppack)+sizeof(PACKET)), "BROADCAST_SIG", 13)==0){
EnterCriticalSection(&timesec);
g_last_time = GetTickCount();
LeaveCriticalSection(&timesec);
}

}

}

free(pdata);
}

_PARAZIT_
25.12.2009, 00:27
на сях не оч понятно.... :(
вот мой код (что неправельно?):

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var TempStr:TStringList;
Command:String;
begin
if not AThread.Terminated and AThread.Connection.Connected then begin

TempStr:=TStringList.Create;
Command:=AThread.Connection.ReadLn;
try
//memo1.Lines.Add(Command);
try
Section.Enter;
Spisok.Add(Command);
finally
Section.Leave;
end;
//================================================== ============================
TempStr.Clear;
TempStr.Add(IntToStr(Length(Command)));
AThread.Connection.WriteStrings(TempStr);
//================================================== ============================
Except
AThread.Connection.Disconnect;
end;
TempStr.Free;
end;
end;

критическая секция создается по FormCreate.

slesh
25.12.2009, 10:33
А вообще синхронизацию очень удобно делать не через критические секции, а через interlockexchenge. Работает очень быстро. Удобно применять в тех случаях когда период ожидания минимальный, но всё таки присутствует.