На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Обратите внимание:
1. Прежде чем начать новую тему или отправить сообщение, убедитесь, что вы не нарушаете правил форума!
2. Обязательно воспользуйтесь поиском. Возможно, Ваш вопрос уже обсуждали. Полезные ссылки приведены ниже.
3. Темы с просьбой выполнить какую-либо работу за автора в этом разделе не обсуждаются.
4. Используйте теги [ code=cpp ] ...текст программы... [ /code ] для выделения текста программы подсветкой.
5. Помните, здесь телепатов нет. Старайтесь формулировать свой вопрос максимально грамотно и чётко: Как правильно задавать вопросы
6. Запрещено отвечать в темы месячной и более давности без веских на то причин.

Полезные ссылки:
user posted image FAQ Сайта (C++) user posted image FAQ Форума user posted image Наши Исходники user posted image Поиск по Разделу user posted image MSDN Library Online (Windows Driver Kit) user posted image Google

Ваше мнение о модераторах: user posted image B.V.
Модераторы: B.V.
Страницы: (4) 1 2 [3] 4  все  ( Перейти к последнему сообщению )  
> Как программно выполнить команду консольного приложения? , Win7, XE7
    Цитата ЫукпШ @
    Да, но только вечером или ночью.
    Спасибо, отлично.
    Максимально упростил свой код, чтобы оценить возможность. Чтобы написать оперативную прогу, буду ориентироваться на твой подход, который считаю совершенно верным.
      Цитата vlad2 @
      Как выполнять команды и читать из командной строки консольного приложения без закрытия самого приложения?
      Спасибо.

      Начнем с того, что термин "конвеер" (pipe) - это однонаправленный канал межпроцессного взаимодействия. Таким образом, одна программа пишет в STDOUT, вторая программа читает из STDIN, и что-то делает. Что делать чтобы вторая программа не закрывалась? Ответ простой - читать STDIN в бесконечном цикле, с возможностью выхода по условию. Увы, но не к сожалению, я Питона не знаю, приведу пример на Перле:

      first.pl
      ExpandedWrap disabled
        #/usr/local/bin/perl
        $| = 1; # flush сразу после очередной операции I/O
        print "print 1;\n";
        print "print 2;\n";
        sleep(2);
        print "print 3;\n";
        sleep(4);
        print "print 4;\n";
        print "EXIT\n";

      next.pl
      ExpandedWrap disabled
        #/usr/local/bin/perl
        $| = 1;  # flush сразу после очередной операции I/O
        while(1) {
          $in = <STDIN>;
          last if ($in =~ /^EXIT\s*$/);
          eval($in);
        }

      Тест запускаем так:
      ExpandedWrap disabled
        perl first.pl | perl next.pl

      В результате первые две команды будут прочитаны и сразу выполнены - выведутся два числа 1 и 2. Потом задержка. Потом вывод числа 3. Потом еще одна задержка. Потом вывод числа 4 и вторая программа "ловит" условие выхода "EXIT", и выполнение завершается.

      Сценарий интерпретаторов, что Перла, что Питона - одинаков. Выполнить скрипт и завершится. Вот Перлу приходит на помощь функция eval(), которая выполняет как код переданную ей строку в качестве аргумента. Может ли такое Питон - я не знаю.

      Далее. Если нужен двусторонний обмен, вангую - нужно определить два именованных пайпа. Для одной программы один канал для записи, второй для чтения. Для второй программы каналы меняются местами. Тогда взаимодействие программ не будет зависеть на каком из терминалов запущены программы.
        Спасибо, JoeUser. Питона тоже не знаю. Мне нужно из внешней программы периодически (не одним скриптом) давать команды Питону и читать его ответы, если они есть. Питон во время всех этих действий должен находиться в памяти. Тоже создаю два пайпа, как написано во многих примерах, правда анонимных...
          Цитата vlad2 @
          Питона тоже не знаю.

          Ну сверскоростное гугление говорит, что eval() в Питоне есть. Так что "принимающий скрипт" можешь писать по образу и подобию моего next.pl, и Питон будет висеть в памяти и читать что ему определишь. А вот для ответов делай именованный пайп.
            Кстати да, а попробуй именованные.
              Цитата JoeUser @
              для ответов делай именованный пайп
              Вроде, для чтения использую PeekNamedPipe, как во многих примерах.
                я несколько подправил класс "cmdShell", и максимально возможно выполнил
                его внутренности в стиле твоей программы.
                В итоге получилось так:
                ExpandedWrap disabled
                  #include "cmdShell_b.h"
                   
                  bool WriteToPython(cmdShell_b& cSh, const char* pStr)
                  {
                   bool bRetC=false;
                   
                   size_t sizeWr = strlen(pStr);
                   if(sizeWr)
                   {
                    if(!cSh.WriteToPipe (pStr,sizeWr)) return false;
                   }
                   
                   MEMT<char> buf;
                   bRetC = cSh.ReadFromPipe  (buf);
                   size_t size = buf.GetDataSize();
                   
                   if((bRetC)&&(size))
                   {
                    for(size_t i=0;i<size;++i) { _tprintf(_T("%c"),buf[i]); }
                   }
                   
                   _tprintf(_T("\n"));
                   return bRetC;
                  }
                  // --------------------------------------------------------------------------
                  int __cdecl _tmain(int argc, char **argv)
                  {
                   _tprintf(_T("\tHello, world!\n"));
                   
                    cmdShell_b cSh;
                    bool bRetC = cSh.Install(_T("python -i"));
                   
                    if(bRetC)
                    {
                     WriteToPython(cSh, "");
                  // пишем файл aa.txt в папку d:\0
                     WriteToPython(cSh, "f=open(\"d:\\\\0\\\\aa.txt\",\"w+\")\n");
                     WriteToPython(cSh, "f.write(\"223\")\n");
                     WriteToPython(cSh, "f.close()\n");
                     WriteToPython(cSh, "exit()\n");
                    }
                    else
                    {
                     _tprintf(_T("bRetC(install)=%d\n"),bRetC);
                    }
                   return 0;
                  }

                Где:
                Скрытый текст


                Файл cmdShell_b.h :
                ExpandedWrap disabled
                  // ---------------------------------------------------------------------------------
                  // file cmdShell_b.h  2020.02.06
                  // ---------------------------------------------------------------------------------
                  #ifndef __cmdShell_b_H__
                  #define __cmdShell_b_H__
                  // ---------------------------------------------------------------------------------
                  //#include "TypeDebugString.h"
                  #include "memt.h"
                  #include "mpipe.h"
                  // ---------------------------------------------------------------------------------
                  // DbgStr::TypeDebugString(_T("%s bConnected=%d"),_T(__FUNCTION__), bConnected);
                  // DbgStr::TypeDebugString(_T("%s buf.GetDataSize()=%d"),_T(__FUNCTION__), buf.GetDataSize());
                  // ---------------------------------------------------------------------------------
                  class cmdShell_b
                  {
                   public:
                   
                  static const size_t TOUT_DEF_ms     = 3000;
                  static const size_t TOUT_DEF_GET_ms = 250;
                  static const size_t SIZE_IN         = 128*1024;
                  static const size_t SIZE_PROXY_IN   = SIZE_IN;
                   
                  static const size_t MAX_COMMLINE_BUFF = 32768;
                   
                   private:
                   
                   protected:
                                bool       bInstalled;
                                MEMT<char> proxyIn;
                   
                                MPIPE               In,Out;
                                STARTUPINFO         si;
                                PROCESS_INFORMATION pi;
                                TCHAR commLineBuff  [MAX_COMMLINE_BUFF];
                                DWORD               dwSizeIn;
                                DWORD               dwSizeOut;
                   
                   
                                size_t     sizePipeInBuf;
                   
                    virtual  bool WINAPI WaitPipeData     (size_t dwToutWait=TOUT_DEF_ms,DWORD* pdwSize=NULL);
                    virtual  bool WINAPI GetPipeData      (MEMT<char>& buf, DWORD dwGot=0, size_t dwToutGet=TOUT_DEF_GET_ms);
                    virtual  bool WINAPI ReadPipe         (bool RetBefore, MEMT<char>& buf, DWORD dwSize);
                    virtual  bool WINAPI AddData          (MEMT<char>& tar, MEMT<char>& sou);
                   
                             bool WINAPI CreatePipes      (void);
                             bool WINAPI PipesExist       (void);
                             bool WINAPI Wait__Process    (DWORD tout);
                             bool WINAPI Check__Pipe      (DWORD *pAvail);  
                             bool WINAPI Read__Pipe       (char *pData,DWORD size,DWORD *pGot);
                             bool WINAPI Write__Pipe      (char *pData,DWORD size,DWORD *pOut);  
                   
                   
                   
                   public:
                                  WINAPI cmdShell_b      (void);
                    virtual       WINAPI ~cmdShell_b     (void);  
                   
                             void WINAPI PreSetPipeInSize (size_t size);
                   
                    virtual  bool WINAPI Install          (const TCHAR* pCommLine);
                   
                    virtual  bool WINAPI WriteToPipe      (const void* pB, size_t size=0);
                    virtual  bool WINAPI WriteToPipe      (MEMT<char>& buf);
                   
                    virtual  bool WINAPI ReadFromPipe     (MEMT<char>& buf, size_t dwToutWait=TOUT_DEF_ms, size_t dwToutGet=TOUT_DEF_GET_ms);
                    virtual  bool WINAPI WriteWaitRead    
                                         (
                                          const void* pB,
                                          size_t      size,
                                          MEMT<char>& buf,  
                                          size_t      dwToutWait  = TOUT_DEF_ms,
                                          size_t      dwToutGet   = TOUT_DEF_GET_ms
                                         );
                   
                             bool WINAPI UnInstall       (void);
                             bool WINAPI Terminate       (UINT uiCode);
                  };
                  // ---------------------------------------------------------------------------------
                  #endif

                Файл cmdShell_b.cpp :
                ExpandedWrap disabled
                  // ---------------------------------------------------------------------------------
                  //   FILE cmdShell_b.cpp 2020.02.05
                  // ---------------------------------------------------------------------------------
                  #include "stdafx.h"
                  #include "cmdShell_b.h"
                  // ---------------------------------------------------------------------------------
                  WINAPI cmdShell_b::cmdShell_b () :
                   
                        dwSizeIn         (0),
                        dwSizeOut        (0),
                        bInstalled       (false),
                        sizePipeInBuf    (SIZE_IN)
                  {
                   ::ZeroMemory(&si, sizeof(si));
                   ::ZeroMemory(&pi, sizeof(pi));
                  }
                  // ---------------------------------------------------------------------------------
                  WINAPI cmdShell_b::~cmdShell_b ()                                                    
                  {
                   UnInstall();
                   if(pi.hProcess) {::CloseHandle(pi.hProcess);}
                   if(pi.hThread)  {::CloseHandle(pi.hThread);}
                  }
                  // ---------------------------------------------------------------------------------
                  void WINAPI cmdShell_b::PreSetPipeInSize (size_t size)                                                    
                  {
                   if(size < SIZE_IN) size = SIZE_IN;
                   sizePipeInBuf = size;
                  }
                  // ---------------------------------------------------------------------------------
                  bool WINAPI cmdShell_b::Install(const TCHAR* pCommLine)
                  {
                   if(!pCommLine) return false;
                   if(bInstalled) return false;
                   if(!proxyIn.Alloc(SIZE_PROXY_IN)) return false;
                   
                   dwSizeIn = (DWORD)sizePipeInBuf;
                   
                   if(!CreatePipes ()) return false;
                   
                   ::ZeroMemory(&si, sizeof(si));  si.cb = sizeof(si);
                   ::ZeroMemory(&pi, sizeof(pi));
                   ::GetStartupInfo(&si);
                   
                   si.dwFlags     = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
                   si.wShowWindow = SW_HIDE;
                   si.hStdOutput  = In.GetWriteHandle();
                   si.hStdError   = In.GetWriteHandle();   //подменяем дескрипторы для
                   si.hStdInput   = Out.GetReadHandle();  // дочернего процесса
                   
                   _sntprintf_s(commLineBuff,ARRAYSIZE(commLineBuff),_TRUNCATE,_T("%s"),pCommLine);
                  // DbgStr::TypeDebugString(_T("%s %s"),_T(__FUNCTION__), commLineBuff);
                   
                      if
                      (
                       !::CreateProcess
                          (
                           NULL,
                           commLineBuff,
                           NULL,
                           NULL,
                           TRUE,
                           CREATE_NEW_CONSOLE,
                           NULL,
                           NULL,
                           &si,
                           &pi
                          )
                      ) return false;
                   
                   bInstalled = true;
                   
                   return true;
                  }
                  // ---------------------------------------------------------------------------------
                  bool WINAPI cmdShell_b::WriteToPipe(const void* pB, size_t size)
                  {
                   if(!bInstalled) return false;
                   if(!pB)    return false;
                   const char* pBuf = (const char*) pB;
                   if(size==0) size=strlen(pBuf);
                   DWORD out=0;
                   bool RetC = false;
                   
                   RetC = Write__Pipe ((char*)pBuf, (DWORD)size, &out);
                   
                   return RetC;
                  }
                  // ---------------------------------------------------------------------------------
                  bool WINAPI cmdShell_b::WriteToPipe(MEMT<char>& buf)
                  {
                   if(buf.GetDataSize()==0) return false;
                   return WriteToPipe(buf.GetPointer(), buf.GetDataSize());
                  }
                  // ---------------------------------------------------------------------------------
                  bool WINAPI cmdShell_b::ReadFromPipe(MEMT<char>& buf, size_t dwToutWait, size_t dwToutGet)
                  {
                   if(!bInstalled) return false;
                   
                   bool RetC    = false;
                   DWORD dwSize = 0;
                   buf.SetDataSize(0);
                   for(int ii=0;ii==0;++ii,RetC=true)
                   {
                    if(!WaitPipeData(dwToutWait, &dwSize)) break;
                    if(!GetPipeData(buf, dwSize, dwToutGet)) break;
                   }
                   return RetC;
                  }
                  // ---------------------------------------------------------------------------------
                  bool WINAPI cmdShell_b::WriteWaitRead(const void* pB, size_t size, MEMT<char>& buf, size_t dwToutWait, size_t dwToutGet)
                  {
                   bool RetC = false;
                   
                   for(int ii=0;ii==0;++ii,RetC=true)
                   {
                    if(pB)
                    {
                     if(!WriteToPipe(pB, size)) break;
                    }
                    if(!ReadFromPipe(buf, dwToutWait, dwToutGet)) break;
                   }
                   return RetC;
                  }
                  // ---------------------------------------------------------------------------------
                  bool WINAPI cmdShell_b::UnInstall(void)
                  {
                   if(!bInstalled) return false;
                   bool RetC=false;
                   
                   RetC = Terminate (0);
                   bInstalled = false;
                   return RetC;
                  }
                  // ---------------------------------------------------------------------------------
                   
                   
                   
                   
                   
                   
                  // ---------------------------------------------------------------------------------
                  // bRetC = exb.ExecBatFile(_T("plink -ssh hostOrIp -P port -l user -pw password"));
                  // ---------------------------------------------------------------------------------
                  bool WINAPI cmdShell_b::WaitPipeData(size_t dwToutWait, DWORD* pdwSize)
                  {
                   bool RetC=false;
                   DWORD dwSize=0;
                   
                   if(pdwSize){*pdwSize=0;}
                   for(size_t i=0;i<dwToutWait;++i)
                   {
                    ::Sleep(1);
                   
                    if(Wait__Process(0)) break;
                   
                    if(Check__Pipe (&dwSize))
                    {
                     if(dwSize==0) continue;
                     else
                     {
                      RetC=true;
                      if(pdwSize){*pdwSize=dwSize;}
                      break;
                     }
                    }
                    else break;
                   
                   }
                   return RetC;
                  }
                  // ---------------------------------------------------------------------------------
                  bool WINAPI cmdShell_b::GetPipeData(MEMT<char>& buf, DWORD dwGot_, size_t dwToutGet)
                  {
                   bool RetC    = false;
                   DWORD dwSize = 0;
                   DWORD dwGot  = dwGot_;
                   if(dwGot) RetC = true;
                   
                   for(size_t i=0;i<dwToutGet;++i)
                   {
                    ::Sleep(1);
                   
                    if(Wait__Process(0)) break;
                   
                    if(Check__Pipe (&dwSize))
                    {
                     if(dwSize==0) {RetC=false; break;}
                     else
                     {
                      if(dwSize > dwGot)
                      {
                       RetC=true; dwGot=dwSize; i=0;
                      }
                     }
                    }
                    else {RetC=false;break;}
                   
                   }
                   
                   RetC = ReadPipe(RetC, buf, dwGot);
                   
                   return RetC;
                  }
                  // ---------------------------------------------------------------------------------
                  bool WINAPI cmdShell_b::ReadPipe(bool RetBefore, MEMT<char>& buf, DWORD dwSize)
                  {
                   if(!RetBefore) return false;
                   if(!buf.Alloc((size_t)dwSize*2)) return false;
                   buf.MemSet(0);
                   if(!buf.SetDataSize(0)) return false;
                   
                   DWORD dwGot=0;
                   
                   if(!Read__Pipe (buf.GetPointer(), (DWORD)buf.GetSize(), &dwGot)) return false;
                   if(!buf.SetDataSize((size_t)dwGot)) return false;
                   
                   return true;
                  }
                  // ---------------------------------------------------------------------------------
                  bool WINAPI cmdShell_b::AddData(MEMT<char>& tar, MEMT<char>& sou)
                  {
                   size_t sizetar = tar.GetDataSize();
                   size_t sizesou = sou.GetDataSize();
                   size_t sizeres = sizetar+sizesou;
                   
                   if(sizeres==0) {tar.SetDataSize(0); return true;}
                   
                   MEMT<char> tmp; if(!tmp.Alloc(sizeres)) return false;
                   
                   size_t ind = 0;
                   for(size_t i=0;i<sizetar;++i){ tmp[ind++]=tar[i]; }
                   for(size_t i=0;i<sizesou;++i){ tmp[ind++]=sou[i]; }
                   tmp.SetDataSize(sizeres);
                   tar = tmp;
                   
                   return true;
                  }
                  //----------------------------------------------------------------------------------
                  bool WINAPI cmdShell_b::CreatePipes (void)
                  {
                   if(PipesExist ())          return true;
                   
                   if(!In. Create(dwSizeIn)) return false;
                   if(!Out.Create(dwSizeOut))return false;
                   
                   return true;
                  }
                  //----------------------------------------------------------------------------------
                  bool WINAPI cmdShell_b::PipesExist (void)
                  {
                   bool rIn  = In.PipeExist();
                   bool rOut = Out.PipeExist();
                   
                   return (rIn && rOut);
                  }
                  //----------------------------------------------------------------------------------
                  bool WINAPI cmdShell_b::Wait__Process (DWORD tout)  
                  {
                   DWORD RetC = ::WaitForSingleObject(pi.hProcess, tout);
                   if(RetC==WAIT_OBJECT_0) return true;
                   return false;
                  }
                  //----------------------------------------------------------------------------------
                  bool WINAPI cmdShell_b::Check__Pipe (DWORD *pAvail)  
                  {
                   return In.CheckPipe(pAvail);  
                  }
                  //----------------------------------------------------------------------------------
                  bool WINAPI cmdShell_b::Read__Pipe (char *pData,DWORD size,DWORD *pGot)  
                  {
                   return In.ReadPipe(pData,size,pGot);  
                  }
                  //----------------------------------------------------------------------------------
                  bool WINAPI cmdShell_b::Write__Pipe (char *pData,DWORD size,DWORD *pOut)  
                  {
                   return Out.WritePipe(pData,size,pOut);  
                  }
                  //----------------------------------------------------------------------------------
                  bool WINAPI cmdShell_b::Terminate (UINT uiCode)
                  {
                   if(!bInstalled) return false;
                   if(!pi.hProcess) return false;
                   
                   if(::TerminateProcess(pi.hProcess, uiCode)) return true;
                   return false;
                  }
                  //----------------------------------------------------------------------------------
                  //  DbgStr::TypeDebugString(_T("%s WaitProcess bRet=%d"),_T(__FUNCTION__),bRet);
                  // ---------------------------------------------------------------------------------


                Пробовал только для x86, но сборка x64 у меня тоже есть.
                Сообщение отредактировано: ЫукпШ -
                  TerminateProcess()... абажаю. В чём проблема была послать ему "quit()"?
                    Цитата Qraizer @
                    TerminateProcess()... абажаю.

                    :lool:
                      Цитата Qraizer @
                      TerminateProcess()... абажаю. В чём проблема была послать ему "quit()"?

                      Допустим, произошла ошибка при пользовании
                      Питоном.
                      Юзер забыл послать ему "exit()".
                      Ещё интереснее получится, если вообще произойдут какие-то ошибки
                      (в процессе отладки нашего приложения) и у нас останется висеть запущенный
                      процесс Питона.
                      А мы завершим работу своего приложения.
                      И задумаем его перезапустить.
                      А это не получится - дочерний процесс уже запущен. "Это фиаско, братан" ©
                      Или получится, но мы не сразу обнаружим вышеупомянутую ошибку
                      и начнём плодить "потерянные" процессы массово.
                      Terminate - это просто предохранитель.
                      Если Питон заканчивает работу штатным образом
                      посредством "exit()", Terminate фактически ничего и не делает.
                      ---
                      Terminate - не так уж редко нужно.
                      ---
                      На самом деле это решение можно критиковать с другой стороны.
                      Просто для упрощения примера я использовал такую реализацию.
                      Предположим, что Питон сам начал запускать различные приложения
                      для своей работы. Много различных процессов.
                      Так вот, нужно перечислить и грохнуть их все.
                      Иначе в результате любой аварии получится неудобная проблема.
                      Более корректный вариант у меня такой:
                      ExpandedWrap disabled
                        // ---------------------------------------------------------------------------------
                        bool WINAPI cmdShell::UnInstall(size_t dwTout)
                        {
                         bool RetC=false;
                         
                         if((bInstalled)&&(pExit))
                         {
                          RetC = WriteToPipe(pExit);
                         
                          if(!WaitProcess((DWORD)dwTout))
                          {
                           BOOL bRKPEX = KillChildProcessesEx();
                           if(!bRKPEX) RetC = false;
                          }
                         }
                         else
                         {
                          if(!KillChildProcessesEx()) RetC = false;
                         }
                         
                         bInstalled = false;
                         return RetC;
                        }
                        // ---------------------------------------------------------------------------------
                      Сообщение отредактировано: ЫукпШ -
                        Цитата ЫукпШ @
                        я несколько подправил класс "cmdShell"
                        Спасибо большое, буду разбираться.
                          ЫукпШ, ты комп тоже reset-ом ребутаешь? Ненуачё, а вдруг какая-то аппликуха откажется отвечать, какой-то драйвер не отпустит свою шелезяку...

                          Добавлено
                          Любое нормально работающее нормальное приложение имеет штатный режим завершения работы. Пользователь ими вполне пользуется. Ты же наверняка не запускаешь таск-менеджер и прибиваешь аппликуху из списка процессов каждый раз? Почему тогда советуешь другим программно делать именно так? Давно Рихтера открывал?

                          Добавлено
                          Цитата ЫукпШ @
                          Terminate - не так уж редко нужно.
                          Никогда не нужно. Ею должен пользоваться только пользователь только из таск-менеджера.
                            Цитата Qraizer @
                            ЫукпШ, ты комп тоже reset-ом ребутаешь? Ненуачё, а вдруг какая-то аппликуха откажется отвечать, какой-то драйвер не отпустит свою шелезяку...

                            Qraizer, ниочём.
                            -----
                            А вообще у меня есть такая функция - в софте у микроконтроллеров - аппаратный reset.
                            Можно даже дать по сети. "И чо ?". Никаких комплексов - если надо, значит сделаем.
                            -----
                            Есть даже такой характерный приём программирования системы.
                            Хорошо известный в узких кругах.
                            Аппаратный сброс на микроконтроллер подаётся от генератора постоянно.
                            Во временном промежутками между сбросами контроллер и выполняет
                            всю работу. Такая вычислительная система не может зависнуть...
                            -----
                            Ты преподавателем работаешь ?

                            Добавлено
                            Цитата Qraizer @
                            Любое нормально работающее нормальное приложение имеет штатный режим завершения работы.

                            А я тебе и ответил - что в штатном режиме Terminate и не используется.
                            Это предохранитель на не предвиденную ситуацию и не штатный режим.
                            Который всегда может возникнуть в любой момент.
                            В том числе и по прямой ошибке программиста.
                              Цитата ЫукпШ @
                              Аппаратный сброс на микроконтроллер подаётся от генератора постоянно.
                              Во временном промежутками между сбросами контроллер и выполняет
                              всю работу. Такая вычислительная система не может зависнуть...
                              :lool: Это пять.
                              Вэлкам ту Холиварс, ЫукпШ. Создавай тему, тут заканчиваем, бо B.V. счас взбесится. Перед созданием рекомендую ознакомиться с такими типами систем, как hosted и freestanding, пригодится.
                              Сообщение отредактировано: Qraizer -
                                Цитата Qraizer @
                                Цитата ЫукпШ @ Вчера, 23:56
                                Terminate - не так уж редко нужно.
                                Никогда не нужно. Ею должен пользоваться только пользователь только из таск-менеджера.

                                Бывает, нужно: сам применяю, когда идёт очередь выполнения задач, и задержка цикла гораздо критичнее принудительного завершения процесса. Приходится прибивать.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (4) 1 2 [3] 4  все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0536 ]   [ 17 queries used ]   [ Generated: 19.04.24, 23:35 GMT ]