Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   С/С++, C#, Delphi, .NET, Asm (https://forum.antichat.xyz/forumdisplay.php?f=24)
-   -   [Delphi] Переключение потоков между собой (https://forum.antichat.xyz/showthread.php?t=164775)

_PARAZIT_ 20.12.2009 01:37

[Delphi] Переключение потоков между собой
 
Товарищи подскажите как можно переключать патоки между собой: например есть паток 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

Цитата:

Сообщение от _s1r1us_
ты каждый поток в ручную создаешь?(T1,T2,T3,...,Tn)? тупо ппц

Согласен, циклом легче в n раз=)

Algol 20.12.2009 02:48

Цитата:

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

как то тупо - это довольно точная формулировка :D

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

_PARAZIT_ 20.12.2009 02:50

...задание такое.
ну может ктонибудь по существу чтонибудь скажет?

Algol 20.12.2009 02:53

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

_PARAZIT_ 20.12.2009 03:02

Цитата:

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

Код:

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

Цитата:

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

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

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

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

Цитата:

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

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

zeppe1in 21.12.2009 02:30

Цитата:

Сообщение от _PARAZIT_
я просто думаю, по нажатию первой кнопки делать 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. Работает очень быстро. Удобно применять в тех случаях когда период ожидания минимальный, но всё таки присутствует.


Время: 10:49