1 00:00:06,600 --> 00:00:08,070 - When you spawn a thread 2 00:00:08,070 --> 00:00:10,533 the spawn function returns a thread handle. 3 00:00:11,430 --> 00:00:15,780 The handle is of type join handle, that's the structure. 4 00:00:15,780 --> 00:00:18,273 And the join handle structure has a join method. 5 00:00:19,140 --> 00:00:20,760 When you call join 6 00:00:20,760 --> 00:00:23,190 your main thread waits 7 00:00:23,190 --> 00:00:24,740 for the other thread to finish. 8 00:00:25,650 --> 00:00:27,330 If the thread is already finished 9 00:00:27,330 --> 00:00:28,720 then it returns immediately 10 00:00:30,180 --> 00:00:31,260 and then you proceed. 11 00:00:31,260 --> 00:00:33,870 So the idea is the main thread, 12 00:00:33,870 --> 00:00:36,030 you kick off a background thread 13 00:00:36,030 --> 00:00:37,710 the main thread does some work 14 00:00:37,710 --> 00:00:39,720 and then the main thread says join 15 00:00:39,720 --> 00:00:42,060 or wait for that other thread to finish. 16 00:00:42,060 --> 00:00:43,560 I'm gonna wait for that other thread to finish 17 00:00:43,560 --> 00:00:46,803 and then I can continue doing some other work afterwards. 18 00:00:47,940 --> 00:00:49,923 So here's a simple example, 19 00:00:51,270 --> 00:00:53,280 I call the thread function. 20 00:00:53,280 --> 00:00:55,930 The thread spawn function returns a joint handle 21 00:00:56,820 --> 00:00:59,981 and then on the joint handle I call the join method. 22 00:00:59,981 --> 00:01:03,180 Now the joint method returns a result 23 00:01:03,180 --> 00:01:06,663 you know the Rust result Enum type. 24 00:01:09,240 --> 00:01:11,610 All right and that basically indicates 25 00:01:11,610 --> 00:01:13,980 how did that other thread finish? 26 00:01:13,980 --> 00:01:16,290 The result could be OK 27 00:01:16,290 --> 00:01:19,350 which means the other thread terminated successfully. 28 00:01:19,350 --> 00:01:20,940 No problem here. 29 00:01:20,940 --> 00:01:22,650 Or the result that you get back 30 00:01:22,650 --> 00:01:24,060 could be an Err 31 00:01:24,060 --> 00:01:26,070 which means the other thread panicked. 32 00:01:26,070 --> 00:01:27,183 It basically failed. 33 00:01:28,260 --> 00:01:29,940 So you have to be a bit careful 34 00:01:29,940 --> 00:01:32,880 if you call handle.join 35 00:01:32,880 --> 00:01:34,470 and the result that you get back, 36 00:01:34,470 --> 00:01:37,200 if you just call unwrap like I've shown here, 37 00:01:37,200 --> 00:01:38,370 what would happen 38 00:01:38,370 --> 00:01:40,833 if the result that you get back was an error? 39 00:01:41,670 --> 00:01:44,100 In that case, you are gonna panic. 40 00:01:44,100 --> 00:01:46,290 Your main thread will also panic. 41 00:01:46,290 --> 00:01:48,690 In other words, your main thread will terminate. 42 00:01:49,822 --> 00:01:51,600 Okay so you have to be a bit careful 43 00:01:51,600 --> 00:01:55,110 just taking the result that this joint method returns 44 00:01:55,110 --> 00:01:57,810 and then unwrap in the result Enum directly 45 00:01:57,810 --> 00:01:59,400 will cause your application 46 00:01:59,400 --> 00:02:01,590 or your thread to fail 47 00:02:01,590 --> 00:02:03,930 if the result 48 00:02:03,930 --> 00:02:07,350 that you got back from the other thread was an error. 49 00:02:07,350 --> 00:02:08,940 A more careful approach 50 00:02:08,940 --> 00:02:13,023 would be to do pattern matching like this, okay? 51 00:02:14,301 --> 00:02:17,790 So you take the handle from the other thread 52 00:02:17,790 --> 00:02:19,020 and you call join, 53 00:02:19,020 --> 00:02:21,810 which basically means wait for that other thread to finish. 54 00:02:21,810 --> 00:02:24,090 It could finish successfully 55 00:02:24,090 --> 00:02:27,453 or it could finish by you know, failing. 56 00:02:28,897 --> 00:02:33,060 So test the result that comes back from the join method 57 00:02:33,060 --> 00:02:34,860 and if the result is OK, 58 00:02:34,860 --> 00:02:36,450 it means I don't care about the value, 59 00:02:36,450 --> 00:02:38,210 I just wanna know that it was OK. 60 00:02:38,210 --> 00:02:41,490 In that case it indicates that the join result is OK 61 00:02:41,490 --> 00:02:44,493 it means that the other thread terminated successfully. 62 00:02:46,705 --> 00:02:49,110 Or if the result that you get back here is an error 63 00:02:49,110 --> 00:02:50,310 then we can print a message 64 00:02:50,310 --> 00:02:51,960 to say the join result is an error. 65 00:02:51,960 --> 00:02:53,970 It means that the other thread failed it. 66 00:02:53,970 --> 00:02:55,110 What it actually means in practice 67 00:02:55,110 --> 00:02:56,760 is that the other thread panicked 68 00:02:58,050 --> 00:03:00,390 it terminated abnormally 69 00:03:00,390 --> 00:03:02,520 and we can get back the result here 70 00:03:02,520 --> 00:03:04,410 and we can decide what to do 71 00:03:04,410 --> 00:03:06,243 if that other thread failed. 72 00:03:07,350 --> 00:03:10,020 So we're gonna run some different scenarios 73 00:03:10,020 --> 00:03:12,030 in our demo code. 74 00:03:12,030 --> 00:03:13,440 I'll start off with main obviously, 75 00:03:13,440 --> 00:03:15,420 and then the the code we're gonna run 76 00:03:15,420 --> 00:03:19,350 it's going to be demo join in thread single 77 00:03:19,350 --> 00:03:20,400 which kind of suggests 78 00:03:20,400 --> 00:03:22,350 that there might later be another demo 79 00:03:22,350 --> 00:03:24,930 about how to join multiple threads. 80 00:03:24,930 --> 00:03:25,763 Watch this space, 81 00:03:25,763 --> 00:03:27,040 that's coming up later on. 82 00:03:28,140 --> 00:03:30,040 Okay, so let's have, look at the code. 83 00:03:30,900 --> 00:03:33,900 Well here we are in the main code. 84 00:03:33,900 --> 00:03:36,450 I'm gonna un-comment the demo for this part. 85 00:03:36,450 --> 00:03:38,793 Demo join in single thread basically, 86 00:03:42,301 --> 00:03:46,263 and it is here, right? 87 00:03:47,340 --> 00:03:50,610 So let me run you through the code for the scenario. 88 00:03:50,610 --> 00:03:55,230 Here is the code that I want to run in a separate thread. 89 00:03:55,230 --> 00:03:57,940 Okay, so I spawn a closure 90 00:03:59,220 --> 00:04:01,230 and that closure is quite simple. 91 00:04:01,230 --> 00:04:02,370 It just prints out the message 92 00:04:02,370 --> 00:04:05,550 to say the background thread 93 00:04:05,550 --> 00:04:07,240 whatever its ideas is starting 94 00:04:08,580 --> 00:04:09,660 waits quite a long time, 95 00:04:09,660 --> 00:04:11,223 it waits 10 seconds. 96 00:04:12,180 --> 00:04:13,500 So there's not a lot going on. 97 00:04:13,500 --> 00:04:15,660 Obviously in reality you'd be doing some real work here 98 00:04:15,660 --> 00:04:17,523 like calling a REST service, 99 00:04:18,630 --> 00:04:20,580 connecting to some database, 100 00:04:20,580 --> 00:04:23,460 doing some complex algorithmic calculations, 101 00:04:23,460 --> 00:04:24,723 something worthwhile. 102 00:04:25,740 --> 00:04:28,410 After that 10 seconds we wake up 103 00:04:28,410 --> 00:04:31,953 and we say this is the end of the background thread. 104 00:04:33,030 --> 00:04:35,040 Later on in about two minutes 105 00:04:35,040 --> 00:04:37,380 I'm going to un-comment this code 106 00:04:37,380 --> 00:04:38,820 and that will indicate 107 00:04:38,820 --> 00:04:42,390 that this thread has actually terminated abnormally. 108 00:04:42,390 --> 00:04:46,170 Okay so come back to un-comment that code in a moment 109 00:04:46,170 --> 00:04:48,300 but as it stands currently 110 00:04:48,300 --> 00:04:50,670 and the closure will get spawned 111 00:04:50,670 --> 00:04:52,200 and well after 10 seconds, 112 00:04:52,200 --> 00:04:53,853 it will complete successfully. 113 00:04:56,190 --> 00:04:58,110 As we know when you call the spawn method 114 00:04:58,110 --> 00:05:01,110 the main thread returns immediately with a handle. 115 00:05:01,110 --> 00:05:03,390 A handle onto that background thread. 116 00:05:03,390 --> 00:05:06,360 So the main thread continuous processing immediately 117 00:05:06,360 --> 00:05:09,438 and the main thread is gonna be busy writing a loop. 118 00:05:09,438 --> 00:05:11,274 So it's gonna loop round 119 00:05:11,274 --> 00:05:14,220 and is that five times or six times? 120 00:05:14,220 --> 00:05:15,930 Six times, isn't it? 121 00:05:15,930 --> 00:05:19,650 It'll print out the main threads' ID 122 00:05:19,650 --> 00:05:20,910 and it's got quite a short delay. 123 00:05:20,910 --> 00:05:24,300 It's gonna loop round basically every half a second, okay? 124 00:05:24,300 --> 00:05:26,370 So the main thread is gonna spin around quite quickly. 125 00:05:26,370 --> 00:05:27,690 That's gonna finish quite quickly. 126 00:05:27,690 --> 00:05:30,693 That's gonna finish after three seconds I think, 127 00:05:31,680 --> 00:05:32,790 whilst this main thread 128 00:05:32,790 --> 00:05:34,290 or this background thread I should say 129 00:05:34,290 --> 00:05:36,270 it's gonna take 10 seconds to complete. 130 00:05:36,270 --> 00:05:37,890 So that's still running 131 00:05:37,890 --> 00:05:41,460 while the main thread finishes that bit of code 132 00:05:41,460 --> 00:05:43,470 and says, well I've done all the work 133 00:05:43,470 --> 00:05:44,910 that I needed to do 134 00:05:44,910 --> 00:05:47,970 now I just need to wait for that other thread to finish. 135 00:05:47,970 --> 00:05:51,180 So I'm not gonna wait for the other thread to end. 136 00:05:51,180 --> 00:05:54,540 Okay, so the main thread is now wait then 137 00:05:54,540 --> 00:05:55,860 and this is how you do it. 138 00:05:55,860 --> 00:05:57,150 Well this is one way to do it. 139 00:05:57,150 --> 00:05:59,973 You can say handle.join.unwrap. 140 00:06:01,320 --> 00:06:04,620 Be careful because what you're assuming there 141 00:06:04,620 --> 00:06:06,840 is that the the other thread 142 00:06:06,840 --> 00:06:08,280 represented by the handle, 143 00:06:08,280 --> 00:06:13,280 the result that you get back is OK, all right? 144 00:06:14,940 --> 00:06:16,980 Well it is OK actually, 145 00:06:16,980 --> 00:06:19,630 our background thread isn't gonna terminate 146 00:06:20,700 --> 00:06:23,340 so you know it's not gonna terminate abnormally I mean, 147 00:06:23,340 --> 00:06:27,080 so after the ten second delay is finished 148 00:06:27,080 --> 00:06:31,500 that should succeed and our application should terminate. 149 00:06:31,500 --> 00:06:34,980 So that's the kind of happy day scenario. 150 00:06:34,980 --> 00:06:36,990 So we'll run the application like this 151 00:06:36,990 --> 00:06:38,130 first of all, 152 00:06:38,130 --> 00:06:39,063 cargo run. 153 00:06:40,950 --> 00:06:42,330 So it's gonna take about 10 seconds 154 00:06:42,330 --> 00:06:44,223 for this application to finish. 155 00:06:47,340 --> 00:06:48,173 There we go. 156 00:06:48,173 --> 00:06:50,730 So the main thread started printed its numbers 157 00:06:50,730 --> 00:06:52,740 101 through the 106 158 00:06:52,740 --> 00:06:55,800 and it completed, 105, sorry quite quickly. 159 00:06:55,800 --> 00:06:59,000 The background thread started there 160 00:06:59,000 --> 00:07:02,970 and then 10 seconds later it finished 161 00:07:02,970 --> 00:07:05,790 and our application was waiting for it to finish 162 00:07:05,790 --> 00:07:06,903 and then we terminate. 163 00:07:08,220 --> 00:07:10,020 So that's fine. 164 00:07:10,020 --> 00:07:11,570 'Course what I could have done, 165 00:07:14,637 --> 00:07:18,210 instead of calling the unwrap function like this 166 00:07:18,210 --> 00:07:21,900 I could have been a little bit more cautious 167 00:07:21,900 --> 00:07:24,300 and I could have had a match statement. 168 00:07:24,300 --> 00:07:26,223 So in this case, 169 00:07:27,330 --> 00:07:29,400 wait for that other thread to finish 170 00:07:29,400 --> 00:07:31,830 it will finish one way or the other. 171 00:07:31,830 --> 00:07:33,060 And then after it's finished, 172 00:07:33,060 --> 00:07:35,220 the result that we get back from the join function 173 00:07:35,220 --> 00:07:38,580 we can see whether the background thread finished normally 174 00:07:38,580 --> 00:07:41,520 in which case join result is OK 175 00:07:41,520 --> 00:07:43,440 or and that's what we are gonna get 176 00:07:43,440 --> 00:07:46,320 because the background thread, you know 177 00:07:46,320 --> 00:07:48,440 there isn't anything dodgy here, 178 00:07:48,440 --> 00:07:50,250 it will terminate normally. 179 00:07:50,250 --> 00:07:51,420 So when we wait for it to finish, 180 00:07:51,420 --> 00:07:52,500 when it has finished 181 00:07:52,500 --> 00:07:53,820 we will eventually get back the result 182 00:07:53,820 --> 00:07:56,513 that says, okay the joint result is OK. 183 00:07:57,486 --> 00:07:58,373 And that's what we're gonna see here. 184 00:07:59,460 --> 00:08:01,470 We're gonna run the application again now 185 00:08:01,470 --> 00:08:03,810 using my more cautious approach to waiting 186 00:08:03,810 --> 00:08:05,910 for the other thread to finish. 187 00:08:05,910 --> 00:08:08,094 So I'm now waiting for the other thread to finish. 188 00:08:08,094 --> 00:08:09,720 You can see the message down here 189 00:08:09,720 --> 00:08:10,950 and then a few seconds later 190 00:08:10,950 --> 00:08:13,290 it will finish the result then comes back, 191 00:08:13,290 --> 00:08:14,640 we test it 192 00:08:14,640 --> 00:08:17,283 and we realize that it says it was OK. 193 00:08:19,372 --> 00:08:22,530 So in that case it says the joint result is OK 194 00:08:22,530 --> 00:08:23,760 thank you for the confirmation. 195 00:08:23,760 --> 00:08:26,100 I knew that was actually gonna happen. 196 00:08:26,100 --> 00:08:27,060 That's all folks. 197 00:08:27,060 --> 00:08:28,860 And that's the end of the demo. 198 00:08:28,860 --> 00:08:31,230 Right so what we need to look at now 199 00:08:31,230 --> 00:08:34,440 is what happens if the main thread panics. 200 00:08:34,440 --> 00:08:36,780 In other words, if the main thread crashes. 201 00:08:36,780 --> 00:08:39,180 So this is, I mean it can happen 202 00:08:39,180 --> 00:08:42,720 threads can go bad, you know, bad things can happen. 203 00:08:42,720 --> 00:08:44,490 So it could well be the case 204 00:08:44,490 --> 00:08:46,123 especially if this thread 205 00:08:46,123 --> 00:08:47,564 is doing some kind of networking 206 00:08:47,564 --> 00:08:50,850 or low level systems related processing. 207 00:08:50,850 --> 00:08:51,683 It could panic. 208 00:08:51,683 --> 00:08:53,760 I've actually caused it to panic deliberately here. 209 00:08:53,760 --> 00:08:55,680 I think this might be the first time 210 00:08:55,680 --> 00:08:57,660 I've shown you the panic macro. 211 00:08:57,660 --> 00:08:59,670 There's a panic macro in Rust 212 00:08:59,670 --> 00:09:04,410 which deliberately causes the thread to terminate, okay? 213 00:09:04,410 --> 00:09:08,130 It's like saying system.exit in other languages. 214 00:09:08,130 --> 00:09:11,730 So this will cause the background thread 215 00:09:11,730 --> 00:09:14,910 which had been kind of waiting for 10 seconds to finish 216 00:09:14,910 --> 00:09:16,830 and then after 10 seconds 217 00:09:16,830 --> 00:09:20,880 that background thread terminates with an error, right? 218 00:09:20,880 --> 00:09:22,290 So that's interesting 219 00:09:22,290 --> 00:09:25,560 because our main thread was waiting for it to terminate 220 00:09:25,560 --> 00:09:27,390 and when it terminates with an error 221 00:09:27,390 --> 00:09:28,920 the result being an error. 222 00:09:28,920 --> 00:09:31,680 We've catered for that quite elegantly 223 00:09:31,680 --> 00:09:33,690 and cautiously to say, 224 00:09:33,690 --> 00:09:35,490 right, it did fail 225 00:09:35,490 --> 00:09:38,310 but at least it didn't pull me down with it. 226 00:09:38,310 --> 00:09:41,190 So we should see this message being displayed now 227 00:09:41,190 --> 00:09:42,240 when we run the application. 228 00:09:42,240 --> 00:09:43,300 So let's run it again 229 00:09:44,580 --> 00:09:47,220 and see this cautious approach 230 00:09:47,220 --> 00:09:48,480 to waiting for the other thread. 231 00:09:48,480 --> 00:09:49,680 It could work, it could fail. 232 00:09:49,680 --> 00:09:51,330 I'd recommend this approach 233 00:09:51,330 --> 00:09:53,370 because then you know what the status was 234 00:09:53,370 --> 00:09:56,493 and you maybe respond to it carefully. 235 00:09:57,935 --> 00:10:01,380 So this thread did panic, okay? 236 00:10:01,380 --> 00:10:02,430 We can't help that. 237 00:10:02,430 --> 00:10:05,170 So we can see that that thread there panicked 238 00:10:06,120 --> 00:10:07,200 with the error message. 239 00:10:07,200 --> 00:10:10,920 Like my error message deliberately panicking dude, 240 00:10:10,920 --> 00:10:14,070 I used to work with a guy everybody was called dude, 241 00:10:14,070 --> 00:10:15,420 it's a funny bloke. 242 00:10:15,420 --> 00:10:16,740 Funny, haha. 243 00:10:16,740 --> 00:10:17,967 So anyway 244 00:10:17,967 --> 00:10:20,820 that's where the background thread terminated, right? 245 00:10:20,820 --> 00:10:23,430 My main thread was waiting for it to terminate 246 00:10:23,430 --> 00:10:26,100 and it realizes in a graceful kind of way 247 00:10:26,100 --> 00:10:28,290 that join result as an error. 248 00:10:28,290 --> 00:10:30,780 Okay so my main thread kind of, 249 00:10:30,780 --> 00:10:32,220 it's like catching an exception 250 00:10:32,220 --> 00:10:33,930 would be the equivalent in other languages, 251 00:10:33,930 --> 00:10:35,400 you absorb the error 252 00:10:35,400 --> 00:10:36,690 but you're still up 253 00:10:36,690 --> 00:10:38,760 and you can still do other things if you want to. 254 00:10:38,760 --> 00:10:42,060 Like you can say that's all folks, right? 255 00:10:42,060 --> 00:10:42,893 So what I'm gonna do 256 00:10:42,893 --> 00:10:44,790 is I'm gonna kind of revert back to my code 257 00:10:44,790 --> 00:10:46,620 to its original form 258 00:10:46,620 --> 00:10:50,940 and I'm going to cause a panic in my background thread 259 00:10:50,940 --> 00:10:53,160 and this will be the last bit of this demo. 260 00:10:53,160 --> 00:10:54,930 So my background thread is gonna panic, 261 00:10:54,930 --> 00:10:56,700 it's gonna fail. 262 00:10:56,700 --> 00:10:58,560 But what I've done here in my main code 263 00:10:58,560 --> 00:11:00,400 is I've gone for the the kind 264 00:11:03,114 --> 00:11:04,500 of rather uncautious approach 265 00:11:04,500 --> 00:11:08,280 where we just wait for the background thread to terminate 266 00:11:08,280 --> 00:11:10,500 and then we just unwrap the result, okay? 267 00:11:10,500 --> 00:11:12,420 If you unwrap a result that's an error 268 00:11:12,420 --> 00:11:15,480 then our thread will also terminate. 269 00:11:15,480 --> 00:11:18,870 So this, if we unwrap an error result 270 00:11:18,870 --> 00:11:20,910 this will cause our main thread to terminate 271 00:11:20,910 --> 00:11:22,770 and that's the end of the program 272 00:11:22,770 --> 00:11:24,270 or that's the end of this thread. 273 00:11:24,270 --> 00:11:25,290 Maybe there's another thread 274 00:11:25,290 --> 00:11:28,470 above us that'll then pick up, okay? 275 00:11:28,470 --> 00:11:30,210 But that will terminate our thread 276 00:11:30,210 --> 00:11:32,040 and that's our main thread in the application. 277 00:11:32,040 --> 00:11:34,410 So our application's gonna basically crash 278 00:11:34,410 --> 00:11:36,363 or panic at that point. 279 00:11:37,380 --> 00:11:39,690 Okay, maybe that's what you want. 280 00:11:39,690 --> 00:11:42,663 Anyway let's see that happen. 281 00:11:44,670 --> 00:11:46,170 So nothing's gonna happen 282 00:11:46,170 --> 00:11:47,880 until the 10 second delay is up 283 00:11:47,880 --> 00:11:49,740 because it's only after 10 seconds 284 00:11:49,740 --> 00:11:51,990 that my background thread terminates 285 00:11:51,990 --> 00:11:54,390 or then panics, okay? 286 00:11:54,390 --> 00:11:55,890 And it does panic, doesn't it? 287 00:11:57,210 --> 00:12:00,210 So the backbone thread panicked 288 00:12:00,210 --> 00:12:03,060 deliberately panicking dude, okay? 289 00:12:03,060 --> 00:12:05,805 And my main thread also panicked. 290 00:12:05,805 --> 00:12:08,820 Like I said, when you unwrap an error result, 291 00:12:08,820 --> 00:12:11,970 your thread, the main thread panics as well. 292 00:12:11,970 --> 00:12:13,930 So the main thread has panicked 293 00:12:16,219 --> 00:12:19,273 and it's here on line 27. 294 00:12:20,400 --> 00:12:22,470 And because that's the main thread in the application 295 00:12:22,470 --> 00:12:24,240 then basically our application, 296 00:12:24,240 --> 00:12:27,750 our process terminates with an error. 297 00:12:27,750 --> 00:12:29,760 So you have a choice. 298 00:12:29,760 --> 00:12:32,400 It is, you know very common 299 00:12:32,400 --> 00:12:34,833 when you kick off a background thread, 300 00:12:36,000 --> 00:12:39,257 it is common to need to wait fit to finish. 301 00:12:39,257 --> 00:12:40,950 Okay so you you do get back a handle 302 00:12:40,950 --> 00:12:42,330 representing the thread 303 00:12:42,330 --> 00:12:44,700 and you do want to join on the handle. 304 00:12:44,700 --> 00:12:47,760 It's up to you whether then you just in a bit cavalier 305 00:12:47,760 --> 00:12:49,378 that's the word I was looking for. 306 00:12:49,378 --> 00:12:50,211 A little bit cavalier, 307 00:12:50,211 --> 00:12:52,456 where you just say I'm gonna see if what's working. 308 00:12:52,456 --> 00:12:53,289 Oh, it didn't. 309 00:12:53,289 --> 00:12:54,210 A more cautious approach 310 00:12:54,210 --> 00:12:56,070 is where you match 311 00:12:56,070 --> 00:12:58,410 and you deal with a successful outcome 312 00:12:58,410 --> 00:13:01,263 and an error outcome on an equal setting.