Two way communication between processes (using pipes) in C

Поделиться
HTML-код
  • Опубликовано: 13 май 2020
  • Check out our Discord server: / discord

Комментарии • 139

  • @JYSERroshanseeam
    @JYSERroshanseeam 3 года назад +32

    you are the best! you taught me this better than my university prof

  • @canaljuunin
    @canaljuunin 2 года назад +13

    I'm amazed by this power you have to explain complex stuff like this in such short videos. I've watched almost every single one of them. thanks!

  • @muhammedozen2699
    @muhammedozen2699 2 года назад +4

    Awesome video. He explains a lot of stuff in as short as 10-20 mins. Great job. We're looking to see more content from you

  • @user-ps5eb9ev6x
    @user-ps5eb9ev6x 11 месяцев назад +1

    I like the return statements in the same line, makes it cleaner and easier to follow. Ty for the great videos.

  • @abhishekhm1264
    @abhishekhm1264 2 года назад +1

    I am so lucky to have found this channel. Just amazing!!

  • @abugslife2461
    @abugslife2461 2 года назад +4

    THANK YOU SO MUCH! You are helping me get through my operating systems class haha This has helped a lot :)

  • @grifo_-cyan7123
    @grifo_-cyan7123 Год назад +1

    Thank you so much! Your C language videos are saving me in my university courses.

  • @diego56780
    @diego56780 3 года назад +1

    Im impressed , amazing job, finally i understand how pipes work.

  • @ajayvembu5901
    @ajayvembu5901 2 года назад

    You are doing an awesome job. Keep going & post more videos of such!! :)

  • @riper7514
    @riper7514 Год назад

    this really helped me understand this concept, thank you very much!

  • @masoudsultanian9887
    @masoudsultanian9887 4 года назад +2

    Great explanation, Thank you
    this is a good example of producer consumer problem with 2 processes with pipe() . could you please create a video explaining Multiple process producers and multiple process consumers using pipe()?

  • @drywater3729
    @drywater3729 3 года назад +1

    Awesome video! Thank you so much!

  • @nostalgicthunder4551
    @nostalgicthunder4551 3 года назад +2

    amazingly explained!

  • @abdullahshahid2822
    @abdullahshahid2822 3 года назад +4

    You look like the nerd of the class.
    Amazingly explained. love ya

    • @CodeVault
      @CodeVault  3 года назад +12

      Always am, always will be :D

  • @hunterkauffman9400
    @hunterkauffman9400 2 месяца назад

    About the same line brackets, my thinking is if the code can be read like a sentence left to right I'll make it one line.
    I always summarize the functionality of inner code blocks when ingesting code, and whenever a code blocks a one liner I can save myself the effort in trying to remember what that code block does and interpret it literally instead of trying to remember what the summary of the high level functionality is

  • @hectordoyle4718
    @hectordoyle4718 4 года назад +13

    1. Great video
    2. In response to your question: returning different values is convenient, easy to debug and understand, so for video purposes it may be a good idea to keep it as it is.
    But speaking of error handling - plain return statement may be not the best choice for more complex applications. So if I may, I'd like to suggest creating a video about error handling alternative approaches. We know that C does not support exceptions that we know form Java and C++, so it would be nice to have something instead.
    All the best!

    • @CodeVault
      @CodeVault  4 года назад +4

      I've seen some nice approaches to error handling in C. Will certainly research this further. Thanks for the feedback! Helps a lot!

    • @juanma513
      @juanma513 Год назад

      Some ideas that come to my mind:
      1) Have a list of macros defining IDs for different errors (e.g.:
      #define ERR_PIPE_CREATION_FAILED 0
      #define ERR_CHILD_NOT_RUNNING 1
      ...). enums instead of macros could work as well
      2) Build a function that receives as parameter one of the previous error codes / IDs and handles it as needed (printing, closing pipes, killing threads, freeing dynamic memory, ..., and finally killing the current process).
      The problem I see with this approach is that the error handler function would need access to those elements to close/kill/free. And make them global could be tricky for large applications. Any other method / drawbacks are welcomed

  • @pedrooriakhi6206
    @pedrooriakhi6206 2 года назад

    You are the best, thank so so much

  • @multivalfran
    @multivalfran Год назад

    Amazing as always

  • @jeremyberry1030
    @jeremyberry1030 Год назад

    I really hope you continue to make content!

  • @HemekSC
    @HemekSC 3 года назад +4

    Hey, great video, i'm viewing this to repeat pipes for my univeristy exam, so, about bidirectional communication, i think that another reason becouse it work (with 2 pipes), is becouse the read syscall is a blocking operation, so if there isn't nothing to read the process wait unitil something is writted, is true?
    Thanks a lot, you earn a new subscriber!

  • @mr.p8766
    @mr.p8766 2 года назад

    you are awesome. many many thanks from german :)

  • @ash_engineering
    @ash_engineering 3 года назад +4

    Please make videos on Pthreads. Your teaching is very nice.

  • @nikeshmali8506
    @nikeshmali8506 Год назад

    so amezing, i got similar assignment, thanks for help, i am watching whole playlist now.

  • @jacerchetoui709
    @jacerchetoui709 Год назад

    Thank you so much! you saved me

  • @therrar1262
    @therrar1262 11 месяцев назад

    Superb material.

  • @anushka_5163
    @anushka_5163 Год назад

    criminally underrated

  • @bama2619
    @bama2619 3 года назад

    Good video. Thank you. A little bit lost with p1 and p2. It will be better to remain like CP and PC.

  • @earnwithcode
    @earnwithcode 3 года назад

    you are awesome in teaching

  • @PatelJashVinodbhaiBCSE
    @PatelJashVinodbhaiBCSE 3 года назад +1

    Thank you bhaiya

  • @poincareelcartografo5406
    @poincareelcartografo5406 10 месяцев назад

    On freeBSD it seems to always work fine with a single pipe.
    Regarding your question, I have made a function in another file with its header.
    You enter what read(), write(), etc... returns and the name of the function that generated it and prints out the error and executes the exit if it is -1 or, otherwise, prints out that the function has been executed. successfully executed.

  • @nadejdapandelieva2249
    @nadejdapandelieva2249 2 года назад

    thanks god that you exist

  • @theflyingdutchman3942
    @theflyingdutchman3942 2 года назад

    Question on closing the file descriptors, is there any reason why you couldn't close them all at the end? Is it good prectice? Or just for the clarity of the explanation? Thinking of doing a close_multiple_fd() to shorten the code a bit, good idea? Absolutely gorgeous videos btw, thanks am million for sharing your knowledge!

    • @CodeVault
      @CodeVault  2 года назад +2

      It's important to close the unused fd's before actually sending data through simply because, when reading, you only get an EOF after all writer fd's have been closed

  • @shaharrefaelshoshany9442
    @shaharrefaelshoshany9442 2 года назад

    Thanks a lot!!
    did the Fifo video of two-way communication already up?

    • @CodeVault
      @CodeVault  2 года назад

      Hmm, it seems I never got around to making it. The idea is exactly the same as in this video but instead of opening 2 pipes you open 2 different fifos

  • @arnabimukherjee4106
    @arnabimukherjee4106 2 года назад

    amazing!!!

  • @user-ug4ow1qq2h
    @user-ug4ow1qq2h 2 месяца назад

    Now it's starting to make sense why I can't pass a variable to an external program and read its output. Every time the C/C++ community talks about pipes they aren't actually talking about calling anything external. They are just talking about a way to pass values within their code. Wish I watched this video earlier, could have saved a couple of days.

  • @liviuq
    @liviuq 3 года назад +1

    Imho, it s clear and easy to follow your return values for the syscalls. I prefer using a macro to check the return value for syscalls because i like to also print why did the call failed.

    • @CodeVault
      @CodeVault  3 года назад +1

      Yes, that's a good idea! I may make a video on this topic, it really cuts down on the amount of code you need to write. Either way, it's very important to check the result of syscalls, otherwise your program might fail unexpectedly.

  • @hingsing1
    @hingsing1 2 месяца назад

    Great video! I wish that during the parts where the terminal result is not relevant, you would close it so we can see more of the code (helps process what is going on overall better). Or zoom out a bit so we can see more lines of code at once.

    • @CodeVault
      @CodeVault  Месяц назад

      Thanks for the feedback, I'll keep that in mind

  • @amaz404
    @amaz404 Год назад

    I love your videos - they are very clear! Is there an advantage to using two pipes vs using a unix domain socket instead?

    • @CodeVault
      @CodeVault  Год назад

      Sockets are bi-directional and can be created as byte streams or datagram sequences while pipes can only be byte streams. Another aspect is that pipes are half-duplex, meaning you can't send and receive data at the same time

    • @amaz404
      @amaz404 Год назад

      @@CodeVault so is there any advantage to using two pipes? It seems that it is much easier to just use a socket

    • @CodeVault
      @CodeVault  Год назад

      @@amaz404 Pipes are generally faster than sockets on the same machine (on certain OSes). On Linux, they seem to have the same performance, so some people recommend just using sockets. Here's a few links you can read:
      home.iae.nl/users/mhx/pipes&socks.html
      stackoverflow.com/questions/1882886/performance-of-sockets-vs-pipes

    • @amaz404
      @amaz404 Год назад

      @@CodeVault Thank you!

  • @tajudeenonigbanjo8809
    @tajudeenonigbanjo8809 Месяц назад

    hey, thank you soo much for the video. I was wondering instead of creating another pipe would it be possible to use the wait() function to have the parent wait for the child process to finish

    • @CodeVault
      @CodeVault  Месяц назад

      Yes but then the pipe can only be used once

  • @ayoubmentag9883
    @ayoubmentag9883 Год назад

    Your videos are just amazing I have just a question , I tried to put wait(NULL) after the parent write to child and then the child recieved and make the calculation ....
    and when I add this wait() it worked , Can we use it like that without creating a new pipe or it could be a problem and we have to create a new pipe ??

    • @CodeVault
      @CodeVault  Год назад

      This could be done but would only work for one read and write operation for the whole process. If you want to reuse the pipes (and the processes), you'd have to create 2 pipes

  • @JussiHemlund
    @JussiHemlund Год назад

    A light bulb appeared above my head. Thx.

  • @kornelkonyari2719
    @kornelkonyari2719 Год назад

    If you did the "homework" from the previous video in the series, you could have faced a similar problem depending on your implementation.
    I did that homework with 1 parent having two children, and each process then summing up a section of the array, and then writing it to a pipe, where the parent was supposed to read from. But then I realised, if I only create one pipe before forking, what if the two children write to the pipe at the same time? What if one finished writing but the other not, then what would happen to the read() call in parent?
    So just to be safe I created a second pipe, so the two children would connect to the parent with different pipes. This way the parent would read from different pipes into different buffers.
    I never found out the answer to the what if situations tho.

    • @CodeVault
      @CodeVault  Год назад +2

      I did some research regarding your questions.
      Regarding your 1st question:
      For the most part having 2 processes write on the same pipe shouldn't be a problem unless the messages are smaller than PIPE_BUF bytes. The messages shouldn't interleave. Although there are situations where the write call has written at least 1 byte in the pipe and is interrupted. At that point the write() call returns a number of bytes written less than expected and it could be difficult to fix on the read() end.
      Regarding the 2nd question:
      If one process finished writing then the read() call should already succeed regardless of the second process' write()
      Still, the solution you ended up implementing, having two pipes, one for each child process is much more reliable

    • @kornelkonyari2719
      @kornelkonyari2719 Год назад

      @@CodeVault Cool, thanks for answering!
      Regarding case1: I never even though about the size of the pipe buffer, but if you want to send only small amounts of data, then you would always face issues, right? I read that you can adjust the pipe buf size with fcntl(), thought I'm not sure as I never needed it.
      And case2: I'm not sure what you mean, do you mean read() only waits for the 1st write to finish? For me that's sounds logical. So then you would need two reads in the parent.
      Well in any case, using two pipes seems to be safer and simpler.
      EDIT: regarding case2: nvm, I read the pipe() man page, and it seems like it is only true if the pipe is widowed. Well the pipe should be widowed anyway, but the man page says that you can still use the F_SETNOSIGPIPE in fcntl(), which would mean the the writing process wouldn't deliver EOF to the reader, meaning the read would keep reading forever, as now none of the writes send the EOF. So one of them should send it to read(), but then the one that sends it would need to be the one that writes last, meaning now the 2nd child has to wait for the 1st child, which would make the whole exercise pointless, as you would lose the benefits of multiple processes calculating at the same time...

  • @christoffer1125
    @christoffer1125 3 года назад +3

    Would another solution not be to put the wait() right after the parent writes the randomly generated number to the pipe? So it would have to wait for the child process to calculate the value, then it is allowed to read it

    • @johndoesson
      @johndoesson 3 года назад +1

      Yes, I thought so too and tried it, it works as long as you terminate the child after it has written to the parent. Although I think there's a reason why you should use 2 pipes because I saw someone say it somewhere else as well but the reason why.. I don't know.

  • @paolamair1257
    @paolamair1257 3 года назад +4

    Would it work if instead of using 2 pipes, we would put a wait() in the parent process right after we generate and write the number?

    • @CodeVault
      @CodeVault  3 года назад +5

      Yes, could work if you control the order of execution of processes with just one pipe... but usually it's better practice to just use 1 pipe per child process.

    • @AramintaK
      @AramintaK 2 года назад +2

      @@CodeVault Don't we have only one child process here, or am I am misunderstanding something?

  • @chuck1156
    @chuck1156 3 года назад

    if the pipe is empty the read() call waits for someone to write in the pipe with write() ?
    shouldnt it return a error value since it tries to read something that doesn't exits?

    • @CodeVault
      @CodeVault  3 года назад +2

      No, when you call "read()", the process waits until there's something to read while the write end is still opened somewhere

    • @rajshah9129
      @rajshah9129 Месяц назад

      @@CodeVault like u said read wait until their is something to read
      so in one pipe when parent write and read it immediately so it will get over but the child will also read it calculate it and write it
      we will not get the correct result as parent process getfinish first but it should not get stuck also why it is getting stuck?

  • @YunusDOGAN-ye7bu
    @YunusDOGAN-ye7bu Год назад

    Write a C program that allows communication between two processes. Dec. Communication with the pipe
    must be provided. Process A must transmit the message it receives from the outside world as an argument to process B, process B
    it should also reverse the same message and send it to process A again. All this message communication is every transaction
    then it should be logged on the screen?

  • @leilanasimi5622
    @leilanasimi5622 2 года назад

    Thank you for the great explanation. I'm writing a similar code, but instead of using " x *= 4 " in the child process, I need to execute another c program and use x as input and get the result back. How can I do that? I'll appreciate your help.

    • @CodeVault
      @CodeVault  2 года назад

      There's this video on the topic, hope it helps: code-vault.net/lesson/oxyoxbvnak:1603732432935

  • @dopetag
    @dopetag 4 месяца назад

    How do we know which process will run first? As I know, the processes run at the same time. How do we know that the parent will run first and send the number to the child? And then the number will be multiplied and send back and only after that read?
    My guess is that read command in child wait for the input. So the write command in parent will run first and then read command in parent will wait for the input. So child has time to calculate and write data to the pipe. When the data is written and parent can read it, the read is executed.
    But what about other commands? Can we predict the order?
    Also, how necessary is wait() in this scenario? Why don't we put read after wait, will it not guarantee that the child process will read and write to this time?

    • @CodeVault
      @CodeVault  4 месяца назад

      wait() is for releasing any resources. Yes, you could call it before reading from the pipe but then you won't be able to read/write multiple times from the process.
      And yes, as you predicted, read() does wait for data to exist in the pipe(). This is fine as long as you have 1 reader and 1 writer and this is also why 1 pipe for two-way communications doesn't really work

  • @jayshah8843
    @jayshah8843 3 года назад

    is this work if we put wait call in else part on next line where y was written so then parent has to wait to terminate child process so now only child process can read y ?(i am taking about the code written before p2 was introduce)

    • @CodeVault
      @CodeVault  3 года назад +2

      I'm not sure what you mean... the wait call can be placed anywhere in the parent as read/write operations are blocking

  • @alyssashen2023
    @alyssashen2023 2 года назад

    For this one, is it possible to do it with dup()? I'm actually very confused when and how to use dup()

    • @CodeVault
      @CodeVault  2 года назад +1

      dup() is only needed for replacing file descriptors with other existing ones. I don't think you need dup() for this

  • @igorthelight
    @igorthelight 2 года назад

    Could we just use wait(NULL) in place of commented printf()?
    I didn't tested it myself

    • @CodeVault
      @CodeVault  2 года назад

      This would work but only for one read/write operation. If you want more than that (which is usually the case) you will need multiple pipes

    • @igorthelight
      @igorthelight 2 года назад

      @@CodeVault Ah, makes sense!
      Thanks!

  • @SekhonSatinder
    @SekhonSatinder Год назад

    On Mac OS, however, I am seeing a slightly different behaviour, to make the parent wait for the child process without using two file descriptors p1 & p2, I had to put wait(NULL) statement right after writing to child in parent process only then it worked. And after adding the two separate file descriptors p1 & p2, even if I remove wait(NULL) statement it worked perfectly.

    • @CodeVault
      @CodeVault  Год назад

      Can you please share the exact code you tried? I would like to test this to understand the difference

    • @SekhonSatinder
      @SekhonSatinder 11 месяцев назад

      @@CodeVault
      #include
      #include
      #include
      #include
      #include
      int main(int argc, const char * argv[]) {
      // insert code here...
      int p1[2]; //Child to parent pipe
      int p2[2]; //Parent to child pipe
      if(pipe(p1) == -1){
      printf("Error opening pipe");
      return 1;
      }
      if(pipe(p2) == -1){
      printf("Error opening pipe");
      return 1;
      }
      int pid = fork();
      if(pid == -1)
      {
      printf("Error getting process ID");
      return 2;
      }
      if(pid == 0) // Child Process
      {
      close(p1[0]);
      close(p2[1]);
      int x;
      if(read(p2[0], &x,sizeof(x)) == -1)
      {
      printf("Error reading from pipe");
      return 3;
      }
      printf("Received from parent process: %d
      ", x);
      x*=4;
      if(write(p1[1], &x,sizeof(x)) == -1)
      {
      printf("Error writing parent process through pipe");
      return 4;
      }printf("Wrote to parent process: %d
      ", x);
      close(p1[1]);
      close(p2[0]);
      }
      else{
      close(p1[1]);
      close(p2[0]);
      srand(time(NULL)); //Parent Process
      int y = rand()%10;
      if(write(p2[1], &y,sizeof(y)) == -1)
      {
      printf("Error writing to child process through pipe");
      return 5;
      }
      printf("Wrote to child process: %d
      ", y);
      // wait(NULL);
      if(read(p1[0], &y,sizeof(y)) == -1)
      {
      printf("Error reading from pipe");
      return 6;
      }
      printf("Received from child process: %d
      ", y);
      //wait(NULL);
      close(p1[0]);
      close(p2[1]);
      }
      return 0;
      }

    • @Mousy
      @Mousy 4 месяца назад

      @@CodeVault this code seems to work on macos:
      #include
      #include
      #include
      int main(void) {
      /* Program objective: Parent writes an integer, child reads it */
      /* Child multiplies it by 4, parent reads the new number */
      /* Interest: Bidirectional communication with pipes */
      /* Another way to achieve this is by using two pipes. One for data transfer Parent->Child */
      /* and the other for data transfer Child->Parent. It seems to work with a single pipe on macOS, but */
      /* it doesn't seem to work on other operating systems. */
      int fd[2];
      if (pipe(fd) == -1) {
      return 1;
      }
      int pid = fork();
      if (pid == -1) {
      return 2;
      }
      else if (pid == 0) {
      /* Child process code */
      int x;
      /* No need for wait because read waits */
      /* for data to be written to the pipe */
      if (read(fd[0], &x, sizeof(x)) == -1) {
      return 3;
      } printf("Here is the child process, I read %d from the pipe.
      ", x);
      x = 4 * x;
      if (write(fd[1], &x, sizeof(x)) == -1) {
      return 4;
      } printf("Here is the child process, I wrote %d to the pipe.
      ", x);
      close(fd[0]); close(fd[1]);
      printf("Here is the child. Goodbye.
      ");
      }
      else {
      /* Parent process code */
      int y1, y2;
      printf("Enter an integer: ");
      scanf("%d", &y1);
      if (write(fd[1], &y1, sizeof(y1)) == -1) {
      return 5;
      } printf("Here is the parent process, I wrote %d to the pipe.
      ", y1);
      wait(NULL); /* Wait for the child process to finish execution */
      if (read(fd[0], &y2, sizeof(y2)) == -1) {
      return 6;
      } printf("Here is the parent process, I read %d from the pipe.
      ", y2);
      close(fd[0]); close(fd[1]);
      }
      return 0;
      }

  • @felixstarr9919
    @felixstarr9919 2 года назад

    How are you using unistd.h in vscode? Are you on Linux? Is it possible to use on Windows10?

    • @CodeVault
      @CodeVault  2 года назад

      unistd.h is Unix specific. In these videos I use Linux, you could also achieve the same thing with WSL on Windows

  • @manindersingh-zn6zz
    @manindersingh-zn6zz Год назад

    Should pipe be created of the same type of data we want to send ?

    • @CodeVault
      @CodeVault  Год назад

      Pipes don't have the concept of types so you don't have to worry about that

  • @souldetox9824
    @souldetox9824 5 месяцев назад

    Can you please create a video on how to do this in MQL4? Just a simple send and receive. I want to send information from one EA installed on a MetaTrader 4 'terminal A' to the EA installed on 'terminal B' (Both the terminals are on the same computer.)

    • @CodeVault
      @CodeVault  4 месяца назад +1

      I will look into

  • @DaStampMASTA2
    @DaStampMASTA2 2 года назад

    so read() waits till the pipe is filled once with some data? or how does the parent read() knows the child process has already written in it. am i correct? :)

    • @CodeVault
      @CodeVault  2 года назад

      Yes, read() waits for data to be in the pipe and write() waits for there to be enough space in the buffer to write to

    • @DaStampMASTA2
      @DaStampMASTA2 2 года назад

      @@CodeVault oh man, thx for the fast answer :)

  • @zyghom
    @zyghom 2 года назад

    @1:58 - I would even skip the curly brackets in my projects in case there is only 1 instruction after "if" for more clarity ;-)

    • @CodeVault
      @CodeVault  2 года назад

      I never skip them for consistency's sake. Also when adding more lines there it doesn't brick my code. Everyone has their own style

  • @MGtvMusic
    @MGtvMusic 3 года назад

    What's the use of srand(time(NULL)); in this program?

    • @CodeVault
      @CodeVault  3 года назад

      It's for seeding the random numbers. Here's an explanation of why you need it alongside rand(): code-vault.net/lesson/9p823km0sm:1603733520459

    • @MGtvMusic
      @MGtvMusic 3 года назад

      @@CodeVault thank you so much

  • @prateekagrawal2894
    @prateekagrawal2894 3 года назад

    I am confused if this can this be used to communicate between c++ and stockfish chess engine?

    • @CodeVault
      @CodeVault  3 года назад +2

      Uhm, I'm not sure what you're trying to achieve here. You'd need to change the underlying code from stockfish to communicate between it and your own process I think.

    • @prateekagrawal2894
      @prateekagrawal2894 3 года назад +1

      @@CodeVault i am trying to achieve inter process communication between c++ and stockfish to predict best chess moves....so, i am currently thinking to create two half-duplex UNIX pipes with pipe() fork() dup2() exec(), one for stdout of program => stdin of chess-engine and vice versa for the other. Hope this can work for me.
      I am learning these concepts now. Btw, thanks for the reply!

  • @ege-vm4xv
    @ege-vm4xv Год назад +1

    Hi, how can we be sure that the parent writes before the child starts to read with respect to p2?

    • @CodeVault
      @CodeVault  Год назад

      You don't need to. The read() function waits until there is something written in the pipe's buffer

    • @techdoctorP
      @techdoctorP Год назад

      Thank you. I had this same question

  • @prakharkothari4351
    @prakharkothari4351 2 года назад

    does it work if instead of creating 2 pipes i make parent wait until child write down the result and then parent reads it. & your videos are great really really helpful. thankyou

    • @prakharkothari4351
      @prakharkothari4351 2 года назад

      #include
      #include
      #include
      #include
      int main(int argc, char *argv[])
      {
      int p1[2];
      if(pipe(p1) == -1)
      {
      printf("An error occured while opening pipe.
      ");
      return 1;
      }
      int pid = fork();
      if(pid == 0)
      {
      //child process
      int x;
      printf("
      Child: Waiting to receive value from parent.
      ");
      if(read(p1[0], &x, sizeof(x)) == -1)
      {
      printf("Child: An error occured while reading from pipe.
      ");
      return 2;
      }
      close(p1[0]);
      printf("Child: Received %d.
      ", x);
      x *= 10;
      printf("Child: Processing value.
      ");
      if(write(p1[1], &x, sizeof(x)) == -1)
      {
      printf("Child: An error occured while writing in pipe.
      ");
      return 3;
      }
      close(p1[1]);
      printf("Child: Wrote down the result.
      ");
      }
      else
      {
      //parent process
      int n;
      printf("
      Parent: Enter a number - ");
      scanf("%d", &n);
      printf("Parent: Writing value entered by user.
      ");
      if(write(p1[1], &n, sizeof(n)) == -1)
      {
      printf("Parent: An error occured while writing in pipe.
      ");
      return 4;
      }
      printf("Parent: Wrote down the value.
      ");
      close(p1[1]);
      printf("Parent: Waiting for child to finish processing.
      ");
      wait(NULL);
      if(read(p1[0], &n, sizeof(n)) == -1)
      {
      printf("Parent: An error occured while reading from pipe.
      ");
      return 5;
      }
      printf("Parent: Number returned from child - %d
      ", n);
      close(p1[0]);
      }
      return 0;
      }
      this is working fine for me does this have have a corner case that i am missing.

    • @CodeVault
      @CodeVault  2 года назад +1

      Hmm, I think this approach will work. The only problem is, you can only send data back to the parent once, since, you have to end the process afterwards. With 2 pipes you can continue sending as much data as you want.

  • @dopetag
    @dopetag 4 месяца назад

    if you fork after the pipe, does it not mean that you have two pipes: one in child and one in parent as all the variables are duplicated?

    • @CodeVault
      @CodeVault  4 месяца назад

      No. The file handlers are being copied on forking. If you call pipe() after fork() you end up with 2 separate pipes

    • @dopetag
      @dopetag 4 месяца назад

      ​@@CodeVault So pipe before fork means that you have 1 pipe, right? Same in both: in the child and int the parent, right?
      In my project I used one pipe before forking and then could close both ends (open, write) in the child and in the parent process (it means 4 of close()). How did it work? if it the same pipe. When the pipes fds are closed, how they can be still available in the parent?

    • @CodeVault
      @CodeVault  4 месяца назад +1

      Whenever you close the fds, it only closes for that specific process. The fds on the other process remain untouched

  • @naitside3410
    @naitside3410 2 года назад

    правильно я понял что 1 pipe лучше использовать для связи в одну сторону, а для связи в другую сторону нужен второй pipes ?

    • @CodeVault
      @CodeVault  2 года назад

      Yes, pipes were designed to only be used for one way communication

  • @codecspy3479
    @codecspy3479 2 года назад +1

    Sir here the child process should wait till the parent process writes some value to the pipe so that the child process can take that value and modify. But where in the program are we ensuring this condition ??

    • @CodeVault
      @CodeVault  2 года назад +4

      It's an intrinsic property of the read call. Basically when you read from a pipe, that read call will wait until there is something to read in that pipe. Similarly a write call will wait until there is space to write to that pipe (the pipe's buffer in this case)

    • @cankoban
      @cankoban 2 года назад +2

      @@CodeVault I think you should put this answer on the description or somewhere because I directly looked for this question after I watched the video. Btw it was a great video again, congrats!

  • @AjayKumar-rv8fw
    @AjayKumar-rv8fw Год назад

    could you please explain how to communicate between two programs?

    • @CodeVault
      @CodeVault  Год назад

      In this video I explain how to do that: code-vault.net/lesson/oxyoxbvnak:1603732432935

  • @alimustafa2682
    @alimustafa2682 2 года назад

    What is the software ur using ??

  • @martinhuang3469
    @martinhuang3469 Год назад

    Can we just wait(NULL) right after write() in the parent process

    • @CodeVault
      @CodeVault  Год назад +1

      Yes, you could. Although that would prevent you from reading and writing anything else between the processes

  • @LYJManchesterUnited
    @LYJManchesterUnited 3 года назад

    Hi if the child process closes the write(fd[1]) of a pipe and I want the parent process to be able to detect when it is closed -> do something , how do I do that? Thabks

    • @CodeVault
      @CodeVault  3 года назад +1

      If all pipe write ends are closed an EOF is emitted on the read ends

    • @LYJManchesterUnited
      @LYJManchesterUnited 3 года назад

      @@CodeVault no all ends closed, just the writing end.

    • @CodeVault
      @CodeVault  3 года назад +1

      yes, just the write end

    • @LYJManchesterUnited
      @LYJManchesterUnited 3 года назад

      @@CodeVault
      But when I did this , I was unable to receive anything from check or print it and it is unable to enter the if statement. Many thanks.
      else if (pid > 0)
      {
      read(fd[0],buf,BUFSIZE);
      printf("%s cpid: %d ppid: %d
      ",buf,cpid,getpid());
      while(1)
      {
      int check = read(fd[0],fub,BUFSIZE);
      printf("%d
      ",check);
      if(check < 1)
      {
      printf("Parent process pid:%d is terminating..
      ",getpid());
      exit(0);
      }
      sleep(1);
      }
      }

    • @CodeVault
      @CodeVault  3 года назад +1

      You forgot to close fd[1] in the parent process

  • @filipneagoe9267
    @filipneagoe9267 2 года назад

    How to implement this in Windows?What are the procedure?

    • @CodeVault
      @CodeVault  2 года назад +1

      You'll have to use the Win32 API for that which quite a bit different than this: docs.microsoft.com/en-us/windows/win32/ipc/anonymous-pipe-operations

  • @appdeveloppement532
    @appdeveloppement532 Год назад

    in the part when you comment the printf("wrote %d
    ", y); in the parent process I try to use wait before read in the parent process and with this even i comment the printf("wrote %d
    ", y); I found the same output without any problem what do you think is a good idea?!
    int main()
    {
    int p1[2];
    int pid;
    if (pipe(p1) == -1 ) return 1;
    pid = fork();
    if (pid == -1) return 2;
    if (pid == 0)
    {
    int x;
    if (read(p1[0], &x, sizeof(x)) == -1) return 3;
    printf("in child : Received %d
    ", x);
    x *= 4;
    if (write(p1[1], &x, sizeof(x)) == -1) return 4;
    printf("in child : Wrote %d
    ", x);
    }
    else
    {
    srand(time(NULL));
    int y = rand() % 10;
    if (write(p1[1], &y, sizeof(y)) == -1) return 5;
    // printf("in parent : Wrote %d
    ", y);
    wait(NULL);
    if (read(p1[0], &y, sizeof(y)) == -1) return 6;
    printf("Result is %d
    ", y);
    }
    close(p1[0]);
    close(p1[1]);
    return (0);
    }

    • @CodeVault
      @CodeVault  Год назад +1

      Yes. That works if you absolutely want to use one pipe. There are two issues with the code though:
      1) You have to wait for the child process to finish execution (might lose performance if the child process does some CPU intensive work after writing to the pipe)
      2) This only works once... If you want to read/write multiple times, you will need a second pipe.
      This is why I recommend using 2 pipes for two-way communication

    • @appdeveloppement532
      @appdeveloppement532 Год назад

      ​@@CodeVault yeah thanks a lot You're a right

  • @erdogancayir
    @erdogancayir Год назад

    thanks for the video i have a problem i made an example like you why it gives different and big numbers for the child

    • @CodeVault
      @CodeVault  Год назад

      Double check that you are sending and receiving the right amount of bytes

  • @andelephantscanfly
    @andelephantscanfly 2 года назад

    Its better to understand it like this 1:50

  • @ammadkhans
    @ammadkhans Год назад +1

    #include
    #include
    #include
    int main(int *argc, char *argv[]){
    int pf1[2];
    int pf2[2];
    if(pipe(pf1)==-1){
    return 1;
    }
    if(pipe(pf2)==-1){
    reuturn 1;
    }
    int pid=fork();
    if(pid==--1){
    return 2;
    }
    if(pid==0){
    close(pf1[0]);
    close(pf2[1]);
    //child process
    int x;
    read(pf1[0],&x,sizeof(x)==-1){return 3;
    }
    printf("recieved %d
    ",x);
    x*=4;
    if(write(pf2[1],&x,sizeof(x))==-1)
    {
    return 4;
    }
    printf("wrote %d
    ",x);
    close(pf1[1]);
    close(pf2[0]);
    }
    else{
    close(pf1[1]);
    close(pf2[0]);
    srand(time(NULL));
    int y=rand()%10;
    if(write(pf2[1],&y,sizeof(y))==-1){
    return 5;
    }
    if(read(pf1[0],&y,sizeof(y))==-1){
    return 6;
    }
    printf("Result is %d
    ",y);
    close(pf1[0]);
    close(pf2[1]);
    }
    }

  • @frogvonneumann9761
    @frogvonneumann9761 2 года назад

    Great video!! Thank you so much!