Potoki w wątku i zablokowane ReadFile

0

Witam,

Co zrobić aby działanie programu było podobne do poniższego przykładu:
http://cpw.net.pl/c++builder/artyku%C5%82/283/

Jednak w tym przypadku funkcja jest wywoływana w wątku, ponieważ w zależności od przełącznika odczytywana jest reakcja

potoku na przesłanie danych do niego (WriteFile()). Chciałbym aby to działało na zasadzie: 1. użytkownik coś wpisuje 2.

Tekst przesyłany jest do potoku 3. Działający wątek zczytuje wynik działania procesu.

Mam następujący kod:

void funkcja_dzialajaca_w_petli_watku_dopoki_mozna()     // jesli mozna = false to watek dziala nadal oczekujac az 

znowu bedzie mozna
{
  
// (...)

  bool bResult;
  char buffer[1024];             
  DWORD bytesRead = 1;
  RtlZeroMemory(buffer, 1024);
  buffer[1023] = 's';   // a to warunek pełnego bufora, 
   //while (!(bResult &&  bytesRead == 0)){
  while ((buffer[1023] != '\0') && !(bResult &&  (bytesRead == 0))){

        RtlZeroMemory(buffer, 1024);
        Memo1->Lines->Append("Czytanie:"+AnsiString(i++));
        bResult = ReadFile(hRead, buffer, 1023, &bytesRead, NULL);

       
        mozna = bResult;
        WaitForSingleObject(hRead, INFINITE);

        RichEdit1->Lines->Add(buffer);
   

  }

  mozna = false;   // bool mozna warunkiem działania funkcji

}

W tym przypadku chce wykorzystać program konsolowy, ale na początek chciałem przetestować na zasadzie interakcji z konsolą
więc tworzę proces:,
CreateProcess(NULL, "cmd", NULL, NULL, TRUE, NULL,NULL, NULL, &startupinfo, &pinfo);

Problem w tym, że w zależności od zastosowanych warunków pętli WHILE, kończy się ona na 2 sposoby:

  1. przebiega raz i na wyniku otrzymuje zaledwie pierwszą linijkę (Microsoft Windows XP [Wersja 5.1.2600])
    2 lub za 2 przebiegiem blokuje się w miejscu:
    bResult = ReadFile(hRead, buffer, 1023, &bytesRead, NULL);
    co w konsekwencji uniemożliwia np. zamknięcie uchwytu hREad albo dalszej interakcji.

W przykładzie z linka jest ok, gdyż wszystko wykonuje się raz i nie w wątku. Po debugowaniu można się domyśleć, że chodzi tu o sposób przytrzymania akcji, dopóki ReadFile nie skończy swojego działania.

Jak przeprowadzić dokładne zczytywanie z potoku w wątku ?

0

AKTUALIZACJA:

Może uproszczę problem:

Program wykonywany krokowo zapełnia bufor całkowicie
("Microsoft Windows XP [Wersja 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
F:\programowanie c++\MyThreadAPI>") i działa OK,

program wykonywany normalnie zapełnia tylko pierwszą linijkę bufora ("Microsoft Windows XP [Wersja 5.1.2600]").
Podejrzewam, że chodzi tutaj w jakiś sposób o synchroniczne/asynchroniczne działanie funkcji ReadFile i szukam sposobu, aby jakoś zatrzymać działanie dopóki bufor nie wypełni się do końca (sleep() nie daje rezultatu).

0

a moze masz raczej problem z synchronizacja watkow np. zapis vs. odczyt albo dodanie tekstu vs wyswietlanie go? i podczas pracy krokowej watki przecinaja sie w prawidlowy sposob, a na wolnosci - zupelnie inaczej? do pomyslenia jest takze, ze moze na wolnosci wszystko leci ladnie tylko watek czytajacy z racji blednych warunkow zakonczenia konczy sie zanim cmd wysle wszystkie napisy?
readfile zwraca Ci dane po linii zapewne dlatego, ze std strumienie we/wy sa buforowane po-linii wlasnie i cmd wysylajac tekst flushuje go na pipe'a wlasnie po kazdym znaku nowej linii..

0

AKTUALIZACJA 2:
Nie wiem z czym jest to związane, jednak, kiedy po utworzeniu procesu usypiam program choćby na 100 ms to odczytywanie działa poprawnie (tak jak krokowo - czyta całą zawartość).

W tej chwili, nie wiem dlaczego, kiedy wysyłam jakiś tekst do potoku funkcją WriteFile(), owszem jest on wpisywany, ale brak reakcji procesu (w normalnej konsoli cmd wpisanie ciągu "vvv2q" powoduje wyświetlenie błędu o niezrozumieniu polecenia - tu jest tylko dodana zawartość)

bool bResult;
          AnsiString  enter = "\n";
         AnsiString wyraz = "2rosamonta3"+enter;///+VK_RETURN;//char(13); // zadna opcja nie skutkuje
         DWORD bytesWritten;

         bResult = WriteFile(hWrite, wyraz.c_str(), wyraz.Length()+1, &bytesWritten, NULL);
         //bResult = WriteFile(hWrite, enter.c_str(), 2, &bytesWritten, NULL);
         
         mozna = true;  // ten warunek uruchamia ponownie petle zczytujaca watku wczesniej przedstawionego

1 użytkowników online, w tym zalogowanych: 0, gości: 1