Communicating between processes (using pipes) in C

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so we looked at how to create processes how to wait for processes we never really looked at how to communicate between processes so I'm going to show you how you can actually do this without just copying the memory over because we saw that if we have memory in our process before actually forking it's going to get copied over but what if I want after it's been forked what if I want something to be sent over to another process how do we do that well there is a functionality in in C that's called a pipe and a pipe what is the what it is it's basically a in memory file you can see it as an in-memory file it's it's a file that only has sort of a buffer that is saved in memory and you can write and read from it okay so in this case if we want to open a pipe what we have to do is just call the function called pipe and this guy takes in a an array of two integers and those two integers are really important they are the file descriptors for this pipe a file descriptor is basically a key key for the access to a file so that we know like to where we want to either read or write data to so in this case I'm going to actually define here a an array of 2fd and this pipe function is going to save inside this array it's going to save the file descriptors that it opens when we create this pipe right so this guy this pipe function creates the pipe and in F D we have the basically the keys to that pipe so we can read or write to it okay so this is very similar to a file let's say except you get to file descriptors you don't only get one so you don't whenever we used F open we only got one sort of file descriptor but in this case we get multiple and it's recommended to check if this factory returns zero so if if we take a look at a tooltip it says that it returns zero if successful so negative one if it's not so if we get negative one and please do a Northwind F on an error occurred with opening top pipe let's say and return okay so now we open the pipe so here we have opened the pipe now we can fork why we can only do it in this order well as I say here in ID equals four the thing is when you fork the file descriptors here get copied over right and these fine descriptors are kind of nice because aside from just getting copied over like only the self from those integrals getting copied over behind-the-scenes those file descriptors are also assigned to the new newly created process so they get inherited what does that mean well that means that if you for example close that file descriptor at one point in a process well that file descriptor in the other process remains open so they sort of have let's say they're independent of each other okay so in this case these two file descriptors get copied over and inherited as well so they can be open or closed independently of each other so now what we can do is say if ID is zero well what I want is just to create a simple program that what does is just asks the user to input a number and then it sends it to the other process I said to the parent process from the child process it sends it to the parent process and the parent process and no printed on the screen or does some operations with it so to do so well we're going to have to declare here a variable so now say int index and well print AB input input a number and then scanf % sandy and then the address of X that's fairly standard and I'm here's where it gets interesting so we want this X to be sent from the child process well in the child process right and bring this guy to be sent to the parent process how do we do that well there's a function called a right which by the way you can actually use not only for pipes you can use to write to any file this guy takes in the file descriptor so we have here FD of well I didn't tell you which is which and why do we have to here well here we have to file descriptors because as the name implies a pipe should have to end right that's how a pipe works in real life so in this case those two ends are stored in here right and then F G of 0 is the read ends where you should read from and FD of 1 is the right end well to which you're gonna you're gonna write the data so in our case we're gonna write 2 FD of one and here's telling me where to get the memory to write from so I want to write well our our X here so I'm going to send in the actual address for X and I want to write in just an integral alright so side opened that should be there should be safe to do next up after we're done writing we should actually close this file descriptor right so like you seem similar to how you do it with files you just say close of f t1 that basically tells anybody that might be listening on that on the other end for this data that well this file code on hold has been closed and you don't have anything to read from it there's no longer any file descriptor that can write that can write to it open so okay this is fine but one more thing that we have to do besides closing the right and is also close the read ends and since the fine descriptors are inherited basically what we have to do is manage our own file descriptors in each of the process so since we're in the child process we also have to close the F D of zero because we don't read anything from that so we can just simply close it like right at the beginning here F D of zero close that and this guy is sort of standard procedure that usual you have like to have a pipe between two processes and usually close one of the ends on every process right so in this case I just closed a few of you because I never read inside this process from this pipe I just write to it okay I hoped it's let's sound and you understood what I what I was saying here now what we have to do is also read from this pipe so similarly we can have here an else and let's define here and in Y and say just read from again it's not going to be F D of one because that's the right end so we have to actually use F G of zero for this let's say F G of zero and again I'm going to read into something so the data is going to be stored into Y here and I'm going to read just the size of int basically four bytes in this case and well as I said above we have to close certain file descriptors so here since we're done reading we should close the FD of the zero the read file descriptor we should also close before doing anything the write descriptor because we don't actually write to it so as you can see we have four close calls because well we have two file descriptors but each of those two got inherited to the other process so we in effect we have four file descriptors that we have to close now since we actually read that y-value let's actually print it on streem so say print f got from child process or sense D and back session you can say you're at the Y value if I run this what I should get is just input on numbers and you'll see here let's say 44 if I hit enter I'm gonna get got from child process port for this is a message from the parent process right remember here ID 0 this is the code for the child process and this is the code for the parent process okay so this is how we distinguish between the two and this guy got actually written to the pipe this X here and really this is just one integral you can write as many bytes as you want you just have to tell it where to sort of write like which data to write how many bytes exactly how many bytes and it's just going to write that many bytes here and on the other end it's going to read that many bytes into this address here it doesn't matter if it's an int if it's a char or whatever just gonna actually plop it in there all right so this is how all works one more thing before I stop the video here is you should check for errors whenever you write or read data so here this right guy if you actually hover over it it's going to say right and might of path to FD returned the number written or negative 1 and negative 1 means there's there was an error or something really bad happened and we should actually tweet this so we should say probably something like if write is negative 1 then let's actually return stuff like - I'm gonna return - because it's different than the one here and it should be pretty obvious that something bad happens we can also type in a message saying that an error occurred we've writing to the path for example and similarly when reading you should do this to say if read of that is negative one if I actually hover over just kind of said it's going to tell me that negative one means something something really bad happened and zero means that we got the end of file descriptor now if we go here we just let's copy this over to here let's say something like with reading from the pipe and then I'm gonna return three here and of course the code is going to work the same way here if I launch this thing I would say I don't know 55 we're still gonna get 55 and of course we can do any operation with this once we read it from here we could just say y equals we'd say Y times 3 why not and if I run this if I for example type in 10 I should get 30 and since we added error checking everywhere in the program here i really suggest you actually do so when 14 as well so for country return negative 1 if it couldn't create a process so we should probably treat this as well see if ID is negative 1 then something like we've let's say and then return well written 1 here we return to 3 so they should be 4 it's it's a nice way to actually keep them different here and now if we if we check everything for errors then when something breaks you're gonna figure it out just from the error message or phone from the error code it's gonna be very easy to figure it out and well usually you shouldn't get any errors if the code is correct but you don't know that the first time you run it and you might actually just run into a rabbit hole where you just kind of search for issues but the issue was something pretty obvious if you had this message shown on the screen now with the fork usually you don't get any error usually you should have process IDs you should have resources to create another process but in some instances your user might be limited to a certain amount of processes and you might not be able to actually fork in this case and you should get an error here so all the new functions that I used here are inside the Uni STD dot H header so you should probably include that I think I forgot to mention that and really that's about it I hope you got something out of this video if you do have any questions do leave them down comments below or on our discord server gonna make sure to actually answer your questions as fast as possible thank you so much for watching take care bye you
Info
Channel: CodeVault
Views: 66,711
Rating: 4.9686451 out of 5
Keywords: pipe, fork, c (programming language), codevault
Id: Mqb2dVRe0uo
Channel Id: undefined
Length: 13min 59sec (839 seconds)
Published: Wed Apr 29 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.