1 00:00:06,170 --> 00:00:11,540 Message passing is where threads communicate by sending each other messages containing data. 2 00:00:11,990 --> 00:00:18,620 For this to be accomplished, Russ uses channels, which is a concept that the standard library provides 3 00:00:18,620 --> 00:00:19,370 for us. 4 00:00:19,760 --> 00:00:23,750 The channel has two ends a transmitter and a receiver. 5 00:00:25,170 --> 00:00:30,480 The transmitter sends data and the receiver takes in that data. 6 00:00:31,410 --> 00:00:38,310 A channel is considered closed when either the transmitter or the receiver end is dropped. 7 00:00:38,550 --> 00:00:44,130 So let's take a look at how these channels work by implementing one where the transmitter will send 8 00:00:44,130 --> 00:00:48,150 a string to the receiver who will then print out that string. 9 00:00:48,660 --> 00:00:52,170 So the first thing we need to do is import an. 10 00:00:53,010 --> 00:00:57,810 The crate that provides channels for us and that is standard sink. 11 00:00:57,840 --> 00:01:03,540 MP SC And now to create a channel we will say 12 00:01:05,760 --> 00:01:09,090 transmitter receiver. 13 00:01:09,270 --> 00:01:15,660 So a tuple equal NPC channel. 14 00:01:17,370 --> 00:01:24,690 Now we can spawn a thread that's going to say and we want to pass in a value. 15 00:01:25,440 --> 00:01:26,730 So we'll say Let Val. 16 00:01:28,120 --> 00:01:32,350 Equals string from 17 00:01:34,450 --> 00:01:35,530 transmitting. 18 00:01:38,830 --> 00:01:42,720 And now we can say transmitter send. 19 00:01:42,730 --> 00:01:46,840 We want to send the string and then it returns the result. 20 00:01:46,840 --> 00:01:48,700 So we need to unwrap it. 21 00:01:51,240 --> 00:01:53,250 For our receiver to receive. 22 00:01:53,250 --> 00:01:55,800 We just say let message equals. 23 00:01:55,860 --> 00:02:04,650 Let me put this semicolon before I forget receiver dot receive and then this also returns a result. 24 00:02:04,650 --> 00:02:11,190 So we need to unwrap it and now we can print out the message that we received. 25 00:02:15,250 --> 00:02:18,770 And if we run this, we see that, we see transmitting. 26 00:02:19,930 --> 00:02:29,620 So MP C stands for multi producer single consumer, which is essentially description of how channels 27 00:02:29,620 --> 00:02:30,040 work. 28 00:02:30,850 --> 00:02:35,440 So now let's look at how we can create multi producers. 29 00:02:35,440 --> 00:02:42,040 But first, let's actually talk about ownership rules and message sending because they do help us write 30 00:02:42,040 --> 00:02:43,990 save concurrent code. 31 00:02:44,080 --> 00:02:53,140 So when we use this send function, it takes ownership of the value being passed in as a parameter and 32 00:02:53,140 --> 00:02:58,780 then when receiver receives it, it takes ownership of that value. 33 00:02:59,600 --> 00:03:04,360 And then obviously that result is returned back here to our message. 34 00:03:04,370 --> 00:03:05,060 So. 35 00:03:06,140 --> 00:03:12,500 There's nothing new with this ownership rule, but it's important to know that that is how ownership 36 00:03:12,500 --> 00:03:14,750 is working inside these channels. 37 00:03:15,910 --> 00:03:24,040 And Russ is doing this so that when we send a value, we don't try to reference or use that value later 38 00:03:24,040 --> 00:03:24,560 on. 39 00:03:24,580 --> 00:03:32,980 So an example of this is if we try to print out our values down here, and this is going to be a compile 40 00:03:32,980 --> 00:03:37,750 time check for us like all the other ownership rules that way. 41 00:03:38,610 --> 00:03:43,620 We cannot reference a value that no longer is valid. 42 00:03:44,130 --> 00:03:47,310 So it is a compile time check, which is great for us. 43 00:03:47,550 --> 00:03:52,740 But now let's take a look at how we can create multiple producers. 44 00:03:52,740 --> 00:03:56,040 So I want to make sure I don't have that air anymore. 45 00:03:56,340 --> 00:03:57,060 And. 46 00:03:58,040 --> 00:04:01,370 Creating multiple producers is actually pretty easy. 47 00:04:01,820 --> 00:04:12,330 So we can say let and this is a shortened way of saying transmitter and we will say transmitter clone. 48 00:04:12,680 --> 00:04:15,080 And now we have another producer. 49 00:04:17,170 --> 00:04:19,480 So I'm going to comment. 50 00:04:20,910 --> 00:04:22,650 All of this out that way. 51 00:04:22,650 --> 00:04:24,060 It's a clean slate. 52 00:04:24,540 --> 00:04:27,810 And now we want to transmit a couple of messages. 53 00:04:27,930 --> 00:04:34,410 So we'll say threads bond and then we'll have let vec equals. 54 00:04:34,920 --> 00:04:40,410 And now we want a new vector to contain some strings. 55 00:04:41,990 --> 00:04:43,370 Transmitting. 56 00:04:44,960 --> 00:04:49,250 And I'm going to copy and paste this to kind of speed it along. 57 00:04:50,690 --> 00:04:51,770 From. 58 00:04:54,970 --> 00:04:56,420 Or original. 59 00:04:59,580 --> 00:05:00,240 All right. 60 00:05:01,350 --> 00:05:03,000 And then to transmit it. 61 00:05:03,000 --> 00:05:06,960 Now that we have a vector, we'll say for each value and vec. 62 00:05:08,780 --> 00:05:12,950 Transmitter Dot send the value. 63 00:05:14,000 --> 00:05:15,470 And now unwrap it. 64 00:05:15,470 --> 00:05:17,210 Because remember it returns a result. 65 00:05:19,180 --> 00:05:21,070 And then we want to close it out. 66 00:05:21,070 --> 00:05:23,350 Now let's format it to make it look pretty. 67 00:05:24,220 --> 00:05:30,130 And now we want to do this again, but with the second producer we created. 68 00:05:30,490 --> 00:05:37,420 So we'll modify that to X and then we will say the clone. 69 00:05:38,800 --> 00:05:39,580 Is. 70 00:05:42,950 --> 00:05:43,230 I can. 71 00:05:43,370 --> 00:05:43,880 There we go. 72 00:05:44,090 --> 00:05:46,460 Trans limiting. 73 00:05:47,700 --> 00:05:48,900 All right, so now what do we have? 74 00:05:48,900 --> 00:05:50,540 We have two threads. 75 00:05:50,550 --> 00:05:51,300 Bond. 76 00:05:52,050 --> 00:05:53,580 Our first producer. 77 00:05:54,800 --> 00:05:57,320 It's going to transmit from original. 78 00:05:57,320 --> 00:06:00,860 And our second one is clone is transmitting. 79 00:06:00,980 --> 00:06:05,630 So now we want to set our receiver up to be able to receive all of these messages. 80 00:06:05,870 --> 00:06:11,480 So we'll say for rec short, for received and receiver. 81 00:06:12,230 --> 00:06:17,120 We want to print out all these values that we. 82 00:06:19,670 --> 00:06:20,510 Received. 83 00:06:23,600 --> 00:06:25,160 And now if we run this. 84 00:06:26,090 --> 00:06:30,890 We see transmitting from original and now we see clone is transmitting. 85 00:06:31,310 --> 00:06:33,590 So that worked exactly as we intended. 86 00:06:33,590 --> 00:06:37,430 We had multiple producers and one single consumer. 87 00:06:37,430 --> 00:06:43,940 But you might be wondering is what happens if our receiver can't keep up with the amount of messages 88 00:06:43,940 --> 00:06:47,120 being put in by our producers? 89 00:06:48,530 --> 00:06:49,220 Well. 90 00:06:49,930 --> 00:06:53,440 The way it works is the messages are being sent. 91 00:06:54,430 --> 00:07:01,600 And are getting put into a queue until the receiver is ready to handle it so the queue could become 92 00:07:01,600 --> 00:07:10,000 overpopulated and when the queue is constantly being added onto and the receiver cannot keep up with 93 00:07:10,000 --> 00:07:17,590 it very well, we actually start to waste resources because we are using resources, sending values 94 00:07:17,590 --> 00:07:25,390 when we actually need to allow the resources to be more allocated to processing the data being sent 95 00:07:25,390 --> 00:07:25,870 in. 96 00:07:26,290 --> 00:07:32,050 So to alleviate this, rust does provide us with a solution called Sync Channel. 97 00:07:33,360 --> 00:07:33,990 And. 98 00:07:35,420 --> 00:07:42,500 What Sync Channel is, is instead of just being channel, we'll say Sync Channel, and then in here 99 00:07:42,800 --> 00:07:43,880 we can put a value. 100 00:07:43,880 --> 00:07:51,350 So I'll put a thousand and a sync channel is going to work the same as a regular channel, but we are 101 00:07:51,350 --> 00:07:55,010 specifying how many values are Q can hold. 102 00:07:56,370 --> 00:08:01,590 And then the send method becomes a blocking operation once the queue is filled up. 103 00:08:01,620 --> 00:08:09,090 So once our queue reaches 1000 values, the next time we hit send, it's actually going to be a blocking 104 00:08:10,860 --> 00:08:16,470 method until our receiver starts to catch up on the amount of values that are in our queue. 105 00:08:17,280 --> 00:08:22,860 So this this in turn allows our receiver to be able to use resources more efficiently. 106 00:08:23,250 --> 00:08:27,660 Remember, blocking does not necessarily mean we lose performance. 107 00:08:27,660 --> 00:08:32,940 We could possibly see resource improvement without losing any throughput in our channel. 108 00:08:32,940 --> 00:08:36,480 So this is something that I just wanted to make you aware of.