1 00:00:06,600 --> 00:00:07,980 - I feel an example coming on. 2 00:00:07,980 --> 00:00:09,330 Let's go into the project, 3 00:00:09,330 --> 00:00:11,760 and have a look at the demo static mutable. 4 00:00:11,760 --> 00:00:12,690 So here we are, 5 00:00:12,690 --> 00:00:15,320 let's go into demo_static_mutable. 6 00:00:16,770 --> 00:00:21,030 And in here I've imported the atomic I32 7 00:00:21,030 --> 00:00:22,130 and the order in enum. 8 00:00:23,010 --> 00:00:25,773 And I've declared a global counter. 9 00:00:26,700 --> 00:00:29,070 So that's thread safe. 10 00:00:29,070 --> 00:00:32,370 And because it's using atomic I32, 11 00:00:32,370 --> 00:00:36,300 I've got a global counter whose initial value is zero. 12 00:00:36,300 --> 00:00:40,050 And then I've got a couple of functions here. 13 00:00:40,050 --> 00:00:44,310 I've got an unsafe function, which has a local counter. 14 00:00:44,310 --> 00:00:46,380 I've got a global counter. 15 00:00:46,380 --> 00:00:49,083 And I've got a local counter, just for this function, 16 00:00:49,950 --> 00:00:50,910 which is mutable. 17 00:00:50,910 --> 00:00:54,303 And I've just got a normal stack-based variable X. 18 00:00:55,170 --> 00:00:57,930 When I try to increment my local counter, 19 00:00:57,930 --> 00:01:02,930 that's just a regular int 32, that's not thread safe. 20 00:01:03,210 --> 00:01:06,240 The only way I can get away with incrementing that static 21 00:01:06,240 --> 00:01:09,183 is because I've declared my function as unsafe. 22 00:01:11,220 --> 00:01:14,160 I also increment the global counter. 23 00:01:14,160 --> 00:01:15,750 Well, that would've been safe anyway 24 00:01:15,750 --> 00:01:18,180 because my global counter is atomic. 25 00:01:18,180 --> 00:01:21,390 So it is implicitly thread safe outta the box. 26 00:01:21,390 --> 00:01:25,110 So I've got a unsafe increment of my local static, 27 00:01:25,110 --> 00:01:30,060 my local stack-based variable, and my global static. 28 00:01:30,060 --> 00:01:33,420 And I output the values of the local count, 29 00:01:33,420 --> 00:01:36,750 my local variable, and my global count, here. 30 00:01:36,750 --> 00:01:39,540 I call that function twice. 31 00:01:39,540 --> 00:01:42,420 Okay, just to see these values change. 32 00:01:42,420 --> 00:01:45,090 And then F2 is a function down here, 33 00:01:45,090 --> 00:01:46,627 let's have a look at F2. 34 00:01:47,813 --> 00:01:52,813 So in F2, in the first function, I used a regular integer. 35 00:01:53,670 --> 00:01:55,470 And when I tried to change it, 36 00:01:55,470 --> 00:01:58,260 that wasn't thread safe, hence the unsafe cue, 37 00:01:58,260 --> 00:02:02,970 oh by the way, did you notice that when I call F1, up here, 38 00:02:02,970 --> 00:02:07,140 from my kind of entry point code, I had to make it unsafe, 39 00:02:07,140 --> 00:02:08,400 in order to call F1. 40 00:02:08,400 --> 00:02:12,750 But F2 is safe, I can just call that function normally, 41 00:02:12,750 --> 00:02:15,510 because in F2 I've been quite careful. 42 00:02:15,510 --> 00:02:18,210 I've declared a static local counter. 43 00:02:18,210 --> 00:02:21,480 This is local to this function, initially zero. 44 00:02:21,480 --> 00:02:24,930 And I incremented in a thread safe kind of way. 45 00:02:24,930 --> 00:02:27,033 I also increment the global counter 46 00:02:27,033 --> 00:02:28,980 in a thread safe kind of way. 47 00:02:28,980 --> 00:02:30,210 And then I output the values. 48 00:02:30,210 --> 00:02:31,620 Let's run the code, or first of all, 49 00:02:31,620 --> 00:02:34,860 let me remember to call that function, from main, 50 00:02:34,860 --> 00:02:37,863 I'm going to call demo static mutable. 51 00:02:38,970 --> 00:02:40,500 Okay, so let's run the code, 52 00:02:40,500 --> 00:02:44,130 and then I'll just run through the statements one more time, 53 00:02:44,130 --> 00:02:45,690 so you can kinda see what's actually been output. 54 00:02:45,690 --> 00:02:46,833 So cargo run. 55 00:02:47,910 --> 00:02:48,903 Cargo run. 56 00:02:51,600 --> 00:02:54,423 And I'm gonna walk you through the code in here. 57 00:02:57,660 --> 00:03:02,660 Right then, so in demo static mutable, here we are. 58 00:03:02,850 --> 00:03:05,223 I call F1, the first time. 59 00:03:06,622 --> 00:03:08,583 And the local counter is zero. 60 00:03:10,920 --> 00:03:13,530 Okay, so that kind of makes sense. 61 00:03:13,530 --> 00:03:16,470 I then increment it to one. 62 00:03:16,470 --> 00:03:20,400 So the local counter is now one, my X is one, 63 00:03:20,400 --> 00:03:22,680 and my global counter is also incremented, 64 00:03:22,680 --> 00:03:27,387 my global counter was zero initially. 65 00:03:28,680 --> 00:03:29,553 There it is. 66 00:03:30,990 --> 00:03:33,000 So let's see what I've done. 67 00:03:33,000 --> 00:03:35,310 I've incremented my local counter. 68 00:03:35,310 --> 00:03:37,530 I've incremented my stack-based variable, 69 00:03:37,530 --> 00:03:40,200 and I've implemented the global counter. 70 00:03:40,200 --> 00:03:43,410 So the local counter is now one, X is one, 71 00:03:43,410 --> 00:03:46,140 and the global counter is also one. 72 00:03:46,140 --> 00:03:50,640 At the end of this function, my local counter is static, 73 00:03:50,640 --> 00:03:52,710 so it is preserved. 74 00:03:52,710 --> 00:03:57,710 My stack-based X is popped off the stack and is gone. 75 00:03:58,560 --> 00:04:01,623 So when I call the function F1 the next time, 76 00:04:02,850 --> 00:04:06,870 then the value of the local counter will still be one, 77 00:04:06,870 --> 00:04:09,363 X will be recreated as zero. 78 00:04:10,380 --> 00:04:12,450 So when I increment my local counter, 79 00:04:12,450 --> 00:04:15,450 my local counter is now two, for this function. 80 00:04:15,450 --> 00:04:17,760 X was recreated from scratch, 81 00:04:17,760 --> 00:04:20,580 because it wasn't static, it was stack-based storage, 82 00:04:20,580 --> 00:04:23,340 so that was back to zero, incremented to one. 83 00:04:23,340 --> 00:04:24,780 My global counter. 84 00:04:24,780 --> 00:04:29,780 The one right at the top is now two as well. 85 00:04:29,880 --> 00:04:32,253 Right, let's see what happens when we call F2. 86 00:04:33,300 --> 00:04:36,600 So in F2, it has its own local counter. 87 00:04:36,600 --> 00:04:39,870 This local counter here is obviously a different one 88 00:04:39,870 --> 00:04:42,510 to the one that we declared in F1. 89 00:04:42,510 --> 00:04:45,240 F1 had its local counter, 90 00:04:45,240 --> 00:04:47,640 and F2 has its own local counter, 91 00:04:47,640 --> 00:04:51,180 so that will be initialized to zero, initially. 92 00:04:51,180 --> 00:04:53,370 And this local X will be zero. 93 00:04:53,370 --> 00:04:55,290 Increment my local counter. 94 00:04:55,290 --> 00:04:59,820 So my local counter here will now be incremented to one. 95 00:04:59,820 --> 00:05:01,140 X will be incremented to one. 96 00:05:01,140 --> 00:05:03,930 My global counter, that's the global counter 97 00:05:03,930 --> 00:05:07,830 right at the top, that's going to be three now. 98 00:05:07,830 --> 00:05:10,830 So, local count is one. 99 00:05:10,830 --> 00:05:13,440 That's correct, that was incremented to one. 100 00:05:13,440 --> 00:05:14,820 My local X is one, 101 00:05:14,820 --> 00:05:17,670 my global counter is retained across all functions, 102 00:05:17,670 --> 00:05:18,633 that's now three. 103 00:05:19,920 --> 00:05:24,920 And then finally, I call my F2 function a second time. 104 00:05:25,860 --> 00:05:27,090 Okay? 105 00:05:27,090 --> 00:05:28,860 So the local counter here is still the value that it was, 106 00:05:28,860 --> 00:05:30,510 it was one. 107 00:05:30,510 --> 00:05:32,730 This variable gets recreated. 108 00:05:32,730 --> 00:05:34,773 Increment my local counter to two. 109 00:05:35,970 --> 00:05:38,100 Increment my local variable to one, 110 00:05:38,100 --> 00:05:40,920 increment the global counter to four. 111 00:05:40,920 --> 00:05:43,680 Okay, so my local count is two. 112 00:05:43,680 --> 00:05:46,080 My local count just for this function 113 00:05:46,080 --> 00:05:48,430 is incremented and preserved, and now it's two. 114 00:05:49,859 --> 00:05:52,950 And my local X gets kinda created and recreated every time, 115 00:05:52,950 --> 00:05:54,810 so that's just one, back to one again. 116 00:05:54,810 --> 00:05:56,853 And my global counter is four. 117 00:05:58,620 --> 00:06:03,180 Okay, so, hopefully that all makes sense. 118 00:06:03,180 --> 00:06:05,250 The main point to take out of this 119 00:06:05,250 --> 00:06:07,650 is that when you have statics, 120 00:06:07,650 --> 00:06:10,050 static variables are not the norm, 121 00:06:10,050 --> 00:06:11,580 it's just taking us a while to explain them, 122 00:06:11,580 --> 00:06:12,990 because they're quite tricky. 123 00:06:12,990 --> 00:06:14,940 But when you do have statics, 124 00:06:14,940 --> 00:06:16,980 the main issue is thread safety. 125 00:06:16,980 --> 00:06:20,850 Because the function can be called on multiple threads. 126 00:06:20,850 --> 00:06:23,670 Multiple threads could access the static. 127 00:06:23,670 --> 00:06:25,500 So whenever you try to change 128 00:06:25,500 --> 00:06:28,350 or, you know, reassign the value to a static, 129 00:06:28,350 --> 00:06:32,250 thread safety is important, you either use mutexes, 130 00:06:32,250 --> 00:06:34,050 if you have a general data type, 131 00:06:34,050 --> 00:06:35,880 or you can use these atomics 132 00:06:35,880 --> 00:06:37,580 if you're dealing with primitives.