1. Pascal / Говнокод #13316

    +129

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    // Delpih 7 отказывается компилировать этот код, тогда как в Delphi 2010 он вполне успешно компилируется.
    // Отчего это?
    
    for pthread in lst do
    ...
    
    >>[Error] Unit1.pas(89): Operator not applicable to this operand type

    Запостил: Stertor, 06 Июля 2013

    Комментарии (40) RSS

    • for ... in ... do в старых пасцалях не было, потому и не работает.
      Ответить
      • Омг. А как же тогда быть, кэп?! Предложите равносильную конструкцию, с защитой от выхода за границы списка.
        Ответить
        • Ну обычный цикл от 1 до длины или от 0 до длины-1, смотря как там индексы идут.
          Ответить
          • А если список потоковый? Элементы добавляются/удаляются в разных потоках. for ..in ..do просто не досчитается элементов и все, а если от нуля по возрастающей - это чревато выходом за границы.
            Ответить
            • А в делфи 7 разве был потокобезопасный список?
              Ответить
              • Как же-с, tthreadlist-с.
                Ответить
                • А внутри цикла много работы? Может просто залочить список на время прохода?
                  Ответить
                  • >>А внутри цикла много работы?

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

                    >>Может просто залочить список на время прохода?

                    Тогда потоки встрянут.
                    Ответить
                    • > Тогда потоки встрянут.
                      Да почему, ты же обращаешься к списку только при старте потока и при его остановке (?). Пробежать по списку - совсем недолго. Ну не тысячи же там потоков, и не сотнями в секунду они стартуют (а если тысячи, то список - плохое решение).

                      Поэтому вот такое предложение:
                      - Перед стартом потока лочим список, проверяем, что такого параметра в нем еще нет, если нету - добавляем тред в список, стартуем его, снимаем лок.
                      - Когда поток собирается выйти - лочим список, удаляем тред из списка, снимаем лок.
                      Ответить
                      • >>Поэтому вот такое предложение:
                        именно так я и делаю.
                        Ответить
                        • А в чем тогда трабла?
                          Ответить
                          • Ах вот оно что: locklist - это еще и вызов метода.
                            Ответить
                            • Ага. И всегда необходимо вызывать парный к нему анлок. Иначе остальные треды не смогут взять лок и повиснут.
                              Ответить
                            • А как получен lst? Это результат вызова LockList?
                              Ответить
                              • да, так точно.
                                Ответить
                                • Значит, это экземпляр класса TList.

                                  Use Items to obtain a pointer to a specific object in the array. The Index parameter indicates the index of the object, where 0 is the index of the first object, 1 is the index of the second object, and so on. Set Items to change the reference at a specific location.

                                  Use Items with the Count property to iterate through all of the objects in the list.


                                  Итого:
                                  for i := 0 to lst.Count - 1 do
                                    begin
                                      pthread := lst.Items[i];
                                      ...
                                  И проблема не в цикле, а в том, как бы не забыть потом анлокнуть.
                                  Ответить
                                  • Товарищи, я чувствую, Вы хотите мне помочь, и не хочу Вас запутывать. Я вроде разобрался. Спасибо.
                                    Ответить
                    • Есть еще банальный вариант, в котором даже потокобезопасный список не нужен. Гуй же у нас однопоточный, поэтому:

                      - заводим TList (или что-то более подходящее, х.з. есть ли эквивалент std::set<std::string> в делфе, и как он называется).
                      - ни в коем случае не лезем к этому листу из каких-либо потоков кроме главного!
                      - при нажатии кнопки проверяем, есть ли строка в списке, если нет - добавляем, запускаем тред
                      - перед остановкой треда запускаем через synchronize() процедуру, которая удаляет строку из списка
                      Ответить
                      • не, слишком вульгарно(

                        gui - потоку: Я тебя породил, я тебя и уьью!.
                        Ответить
                        • Товарищи, объясните мне, пожалуйста, суть многопоточности.
                          Допустим, есть многопоточный прокси-чекер, загружен список из 10 проксей для проверки, счетчик потоков установлен на 50. Что в этом случае дадут дополнительные потоки, при проверке проксей? Я бы понимал, если на один прокси-один поток. Но 50! Или один поток тут же сменяет другой, если он завис при проверке, и этим обеспечивается высокая скорость выполнения?
                          Ответить
                          • Хотя бы на примере этого

                            http://govnokod.ru/13317

                            Сколько ни пытался вникнуть, не доходит.
                            Ответить
                            • >>function getnumberproxy:integer;
                              begin
                              if ind<>form1.Memo1.Lines.Count then
                              inc(ind);
                              result:=ind;
                              end;

                              Эта процедура возвращает номер текущей строки в мемо1. До тех пор, пока в мемо есть строки, поток крутит цикл. Но это 1 уникальный поток. А все остальные тихо дрочат в сторонке. НЕТ здесь многопоточногсти, сынок.
                              Ответить
                              • А если объявить ind как threadvar?
                                Ответить
                              • Ну допустим, если это так, то зачем тогда крутить цикл?

                                procedure TMyTr.Execute;
                                var
                                s,resp,ip,port:string;
                                cw,i:integer;
                                begin
                                  http:=TIdHTTP.Create(nil);
                                  cw:=getnumberproxy;
                                  while cw<form1.Memo1.Lines.Count do
                                  begin
                                    s:=form1.Memo1.Lines[cw];
                                    i := Pos(':',s);
                                    IP := Copy(s,1,i-1);
                                    PORT := Copy(s,i+1,Length(s));
                                
                                    try
                                      http.ProxyParams.ProxyServer:=ip;
                                      http.ProxyParams.ProxyPort:=StrToInt(port);
                                      http.ReadTimeout:=Form1.SpinEdit2.Value*1000;
                                      resp:=http.Get('http://ya.ru/');
                                      if pos('ya.ru',resp)<>0 then
                                      form1.Memo2.Lines.Add(ip+':'+port);
                                      except
                                        end;
                                      cw:=getnumberproxy;
                                      checked:=checked+1;
                                      end;
                                  http.Free;
                                
                                end;
                                Ответить
                                • >>try
                                  http.ProxyParams.ProxyServer:=ip;
                                  http.ProxyParams.ProxyPort:=StrToInt(por t);
                                  http.ReadTimeout:=Form1.SpinEdit2.Value* 1000;
                                  resp:=http.Get('http://ya.ru/');
                                  if pos('ya.ru',resp)<>0 then
                                  form1.Memo2.Lines.Add(ip+':'+port);
                                  except

                                  даже проверки нет connected true или нет, один хуй хуячит
                                  Ответить
                      • > эквивалент std::set<std::string> в делфе, и как он называется.
                        THashedStringList есть. В седьмой дельфи он по идее в IniFiles объявлен.
                        Ответить
      • Да ладно? У меня даже в TP 7 работало:
        const
          lst: set of char = ['T', 'r', 'o', 'l', '0', '1', 'O'];
        var
          pthread: char;
        begin
          for pthread in lst do
            Write(pthread);
          Writeln
        end.
        Тест для FPC: http://ideone.com/IjUIZL
        Ответить
        • Минусующий прав. В TP и в старых Дельфи была конструкция if ... in, но не было for ... in.Вообще in можно было использовать в любом логическом выражении, но for был только для отрезков.
          Ответить
          • Судя по минусу, в твоих рассуждениях ошибка. Попробуй метод "от обратного".
            Ответить
            • Я наверняка зелёную краску и жирный шрифт не там, где нужно, применил.
              Ответить
              • Холодно, жми f8.
                Ответить
                • movb	$0,%bl
                  	decb	%bl
                  	.balign 4,0x90
                  .Lj7:
                  	incb	%bl
                  	movzbl	%bl,%eax
                  	btl	%eax,(%esp)
                  	jnc	.Lj9
                  	movb	%bl,32(%esp)
                                ....................
                  .Lj9:
                  	cmpb	$255,%bl
                  	jb	.Lj7
                  Ух, ты! В ФПЦ for ... in трансформируется в обычный for с пропусками типа if not i in lst continue. Так не интересно.
                  Ответить
        • >>Тест для FPC: http://ideone.com/IjUIZL

          А где там отладчик?)

          (trollface)
          Ответить
    • Заебал со своим паскалем, его не знает никто кроме школьников.
      Ответить
      • показать все, что скрытоПаскаль аки латынь. А латынь - дохлый язык; солус кум сола нон когитабунтур ораре "Патер Ностер"
        (solus qum sola, non cogitabuntur orare Pater Noster)
        Но ведь Делфай не паскаль, Паскаль не Делфай.
        Ответить

    Добавить комментарий