Hello.

He broke his head thinking that he was wrong and came to the conclusion that in general everything is wrong, there are suspicions that it is impossible to do this.
The essence of the program is that one stream performs calculations, creates a channel and gives the result to another stream, which, after transformations, displays the data on the screen.

Here is the main function, everything is clear. We create two streams, nothing goes to their input.

int _tmain(int argc, _TCHAR* argv[]) { DWORD dw; HANDLE IDThread[2]; IDThread[0]=CreateThread(NULL,0,MainTread,0, 0, &dw); IDThread[1]=CreateThread(NULL,0,MinorThread,0, 0, &dw); WaitForMultipleObjects(ThrCount,IDThread,TRUE,INFINITE); system("pause>>void"); return 0; } 

Next, the 1st thread. (I simplified the program to horror, leaving the most basic).

 DWORD WINAPI MainTread(LPVOID Insert) { wchar_t *PName = L"\\\\.\\pipe\\TransmitPipe"; //Имя ΠΊΠ°Π½Π°Π»Π° HANDLE hPipe; //ЭкзСмпляр самого ΠΊΠ°Π½Π°Π»Π° BOOL Success; //ΠŸΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ значСния Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ функциями DWORD byteCnt, byteWrt; //Число Π±Π°ΠΉΡ‚ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π°Π΄ΠΎ Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Π² ΠΏΠΎΡ‚ΠΎΠΊ ΠΈ счСтчик Π±Π°ΠΉΡ‚ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎ записанных Π² ΠΊΠ°Π½Π°Π». char X[10]; //Π‘ΡƒΠ΄Π΅ΠΌ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π²Ρ‚ΠΎΡ€ΠΎΠΌΡƒ ΠΏΠΎΡ‚ΠΎΠΊΡƒ этот Ρ‡Π°Ρ€ for(int i=0; i<10; i++) {X[i]='9';} //Π—Π°ΠΏΠΎΠ»Π½ΠΈΠΌ Π΅Π³ΠΎ дСвятками X[i]='\0' //На всякий случай //Π‘Π°ΠΌΠΎΠ΅ интСрСсноС hPipe = CreateNamedPipe(PName, PIPE_ACCESS_DUPLEX,PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,PIPE_UNLIMITED_INSTANCES,4096,4096,0,NULL); if(hPipe!=INVALID_HANDLE_VALUE) {std::cout<<"1) Pipe create is OK \n";} //ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ°. Если экзСмпляр Π½Π΅ Π²Π΅Ρ€Π½ΡƒΠ» Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π·Π½Π°Ρ‡ΠΈΡ‚ ΠΊΠ°Π½Π°Π» создан. 1) - ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ Ρ‡Ρ‚ΠΎ ΠΏΠΎΡ‚ΠΎΠΊ 1Ρ‹ΠΉ. Success = ConnectNamedPipe(hPipe, NULL); //ОТидаСм запроса Π½Π° соСдинСниС с этим ΠΊΠ°Π½Π°Π»ΠΎΠΌ if(Success){std::cout<<"1) Connect is OK \n";} //Если Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ 1, Π·Π½Π°Ρ‡ΠΈΡ‚ соСдинСниС ΠΏΡ€ΠΎΡˆΠ»ΠΎ Success = WriteFile(hPipe, X, byteCnt, &byteWrt, NULL); //ПишСм наш Π₯ Π² ΠΊΠ°Π½Π°Π» hPipe if(Success){std::cout<<"1) Write is OK \n";} //Ѐункция Π²Π΅Ρ€Π½ΡƒΠ»Π° 1 - всС ОК } 

Next, the second stream (There in the output messages on the screen will be "2)").

 DWORD WINAPI MinorThread(LPVOID Insert) { wchar_t *PName = L"\\\\.\\pipe\\TransmitPipe"; //ВсС Ρ‚Π°ΠΊ ΠΆΠ΅, это имя ΠΊΠ°Π½Π°Π»Π° HANDLE hPipe; //ЭкзСмпляр BOOL Success; DWORD pMode; //Π­Ρ‚ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Ρ€Π΅ΠΆΠΈΠΌ Ρ€Π°Π±ΠΎΡ‚Ρ‹, ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ Π½ΠΈΠΆΠ΅. char X[10]; //Бюда пишСм, Ρ‚ΠΎ Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈΡˆΠ»Π΅Ρ‚ ΠΊΠ°Π½Π°Π» hPipe = CreateFile(PName,GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); //ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌΡƒ ΠΊΠ°Π½Π°Π»Ρƒ (созданному Π² 1ΠΎΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ΅) if(hPipe!=INVALID_HANDLE_VALUE) {std::cout<<"2) File create is OK \n";} //ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° (Ρ‚ΠΎΡ‚ ΠΆΠ΅ смысл Ρ‡Ρ‚ΠΎ ΠΈ Π² 1П) Success = WaitNamedPipe(PName, NMPWAIT_WAIT_FOREVER); //ОТиданиС ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΊ экзСмпляру ΠΊΠ°Π½Π°Π»Π° if(Success){std::cout<<"2) Pipe avelible OK \n";} //Канал доступСн Ссли всС Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ pMode = PIPE_READMODE_MESSAGE; //Π Π΅ΠΆΠΈΠΌ чтСния сообщСний Success = SetNamedPipeHandleState(hPipe, &pMode, NULL, NULL); //ΠŸΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊΠ°Π½Π°Π»Π° Π² Ρ€Π΅ΠΆΠΈΠΌ чтСния сообщСний if(Success){std::cout<<"2) Readmode is OK \n";} Success = ReadFile(hPipe, Π₯, 4096, &byteWrt, NULL); //Π§Ρ‚Π΅Π½ΠΈΠ΅ ΠΈΠ· экзСмпляра Π² Π₯. 4096 - Ρ€Π°Π·ΠΌΠ΅Ρ€ Π±ΡƒΡ„Π΅Ρ€Π° ΠΏΠΎΠ΄ Ρ‡ΠΈΡ‚Π°Π΅ΠΌΠΎΠ΅ сообщСниС if(Success){std::cout<<"2) Read is OK \n";} std::cout<<X; } 

Displays 0.

But he writes:

alt text

That is, the channel is created and data is written there, and even the second stream is connected to it, in general, everything stops working.

So the question: Was it a good idea to throw a channel from stream to stream? Maybe you know where I nakosyachil code?


Put semaphores. The second stream is trying to read from the channel: alt text

The essence of the error: MSDN

 ERROR_NOACCESS 998 (0x3E6) Invalid access to memory location. 

Question: Why? Writing to the channel is normal, why is there an error when reading, and yes even with a complaint about a section of memory.

  • @alexlz I can't comment on the answer = (Thanks, now it's clear why there is a problem with memory) - BlackOverlord

1 answer 1

Using pipes for data transfer within a single process is the wildest overkill, it would be worse to use sockets.

To transfer data from a stream to a stream, use a shared data structure (for example, std :: queue), protecting it from simultaneous access using a mutex (for example, CRITICAL_SECTION, if you want Windows-specific, or better std :: mutex , if your compiler supports standard C ++ 11).

You really need a Producer-Consumer pattern.

Welcome to the multi-threaded programming universe!


Regarding your code - maybe the reading thread is waiting for 4096 bytes of data to be finally put into the pipe? Try to read one byte as a debug.

  • Thank you) I thought so, looking at how sad the result was, but alas, this program was not my idea ... - BlackOverlord
  • @BlackOverlord: look at the update of the answer, so about the pipes - VladD
  • I read about semaphores, I'll try) - BlackOverlord
  • @BlackOverlord: oh! semaphores megarulosis! although I would use the condition variable. - VladD
  • 2
    Well, the question is not in the MainThread installation byteCnt to write (apparently this has already been fixed). But the length of the buffer for reading lpNumberOfBytesToRead in the ReadFile should not be larger than the size of the buffer X itself (otherwise there may be memory problems) - alexlz