1 00:00:07,360 --> 00:00:09,360 NATE HARDISON: When you've got multiple programs open on a 2 00:00:09,360 --> 00:00:11,250 computer, it seems like everything's 3 00:00:11,250 --> 00:00:12,880 running at the same time. 4 00:00:12,880 --> 00:00:15,350 For example, you might be working in a web browser like 5 00:00:15,350 --> 00:00:19,360 Firefox or Internet Explorer, listening to music on iTunes, 6 00:00:19,360 --> 00:00:21,490 and writing an essay with Word. 7 00:00:21,490 --> 00:00:24,240 However, under the hood, the programs actually 8 00:00:24,240 --> 00:00:25,830 run one at a time. 9 00:00:25,830 --> 00:00:29,750 It's the job of the operating system, Windows, Mac OSX, or 10 00:00:29,750 --> 00:00:33,070 Linux, to manage each of these separate processes, as the 11 00:00:33,070 --> 00:00:35,900 programs are known, and switch between them so that when you 12 00:00:35,900 --> 00:00:38,610 go from checking your Facebook page to working on your essay 13 00:00:38,610 --> 00:00:41,590 again, Word is the one that's running. 14 00:00:41,590 --> 00:00:44,890 >> Sometimes, though, we want programs themselves to be able 15 00:00:44,890 --> 00:00:47,440 to do multiple things like this, too. 16 00:00:47,440 --> 00:00:49,630 If you're like me, you probably have a bunch of 17 00:00:49,630 --> 00:00:52,730 different tabs open in your web browser, one for email, 18 00:00:52,730 --> 00:00:55,070 one with a calendar, and so on. 19 00:00:55,070 --> 00:00:58,270 We could treat each tab as a separate program or process, 20 00:00:58,270 --> 00:01:01,300 like Google Chrome does, but many programs use a 21 00:01:01,300 --> 00:01:04,430 lighter-weight version of a process called a thread. 22 00:01:04,430 --> 00:01:07,190 >> A thread is just another unit of processing ,a set of 23 00:01:07,190 --> 00:01:10,100 instructions or code that can "run", quote unquote, 24 00:01:10,100 --> 00:01:12,560 concurrently with other threads. 25 00:01:12,560 --> 00:01:15,150 This is what makes it possible for you to browse Facebook 26 00:01:15,150 --> 00:01:17,940 while listening to me in the background or to have two 27 00:01:17,940 --> 00:01:20,790 YouTube videos playing at the same time. 28 00:01:20,790 --> 00:01:24,660 So, this general topic, known as concurrency, typically 29 00:01:24,660 --> 00:01:26,930 doesn't come up so early in computer science courses 30 00:01:26,930 --> 00:01:29,790 because the lower-level details require discussion of 31 00:01:29,790 --> 00:01:31,930 operating systems and the like. 32 00:01:31,930 --> 00:01:34,170 However, the programming language we use at the 33 00:01:34,170 --> 00:01:38,000 beginning of CS50, Scratch, provides some nifty tools to 34 00:01:38,000 --> 00:01:40,390 make it easier to write programs with multiple things 35 00:01:40,390 --> 00:01:42,390 going on at once. 36 00:01:42,390 --> 00:01:45,050 >> When you build Scratch programs, you're constantly 37 00:01:45,050 --> 00:01:46,760 working with threads. 38 00:01:46,760 --> 00:01:49,770 Each Scratch script, which is a code block that begins with 39 00:01:49,770 --> 00:01:52,600 one of the "when" puzzle pieces, can be thought of 40 00:01:52,600 --> 00:01:54,380 as a separate thread. 41 00:01:54,380 --> 00:01:58,040 Let's look at a simple Scratch program to see how this works. 42 00:01:58,040 --> 00:02:01,730 >> Here, we've got a fish object, or sprite, with two scripts 43 00:02:01,730 --> 00:02:05,000 that both start when we click the little green flag button. 44 00:02:05,000 --> 00:02:07,290 The first script controls the fish's motion. 45 00:02:07,290 --> 00:02:09,850 When the green flag is clicked, the fish gets placed 46 00:02:09,850 --> 00:02:12,450 on the left side of the screen, called the stage, 47 00:02:12,450 --> 00:02:14,090 facing to the right. 48 00:02:14,090 --> 00:02:17,070 Then, in a set of instructions that'll run forever, until we 49 00:02:17,070 --> 00:02:20,270 stop the program, the fish glides to the right side, 50 00:02:20,270 --> 00:02:22,900 turns around, goes back to the left side, and 51 00:02:22,900 --> 00:02:24,470 turns around again. 52 00:02:24,470 --> 00:02:27,410 The second script controls the fish's thought process. 53 00:02:27,410 --> 00:02:29,290 It turns out that this is a hungry fish. 54 00:02:29,290 --> 00:02:32,080 So after waiting for 3 seconds, the fish will think, 55 00:02:32,080 --> 00:02:34,420 "I'm hungry," for a fourth second. 56 00:02:34,420 --> 00:02:36,440 This script also runs forever. 57 00:02:36,440 --> 00:02:38,940 And as we see, from running the program by clicking the 58 00:02:38,940 --> 00:02:41,730 green flag, both scripts appear to execute 59 00:02:41,730 --> 00:02:43,100 simultaneously. 60 00:02:43,100 --> 00:02:46,460 The fish moves and thinks at the same time. 61 00:02:46,460 --> 00:02:49,030 >> Since the poor fish looks so hungry, let's add in some 62 00:02:49,030 --> 00:02:50,670 cheesy puffs for it to eat. 63 00:02:50,670 --> 00:02:53,060 Hopefully they won't disintegrate in the water. 64 00:02:53,060 --> 00:02:55,560 When we add in a second sprite, we'll also be able to 65 00:02:55,560 --> 00:02:58,020 add in scripts corresponding to that sprite. 66 00:02:58,020 --> 00:02:59,580 And, hence, there'll be another set of 67 00:02:59,580 --> 00:03:00,830 threads that'll run. 68 00:03:03,590 --> 00:03:06,270 To give the user of our program control over when the 69 00:03:06,270 --> 00:03:09,340 hungry fish gets food, let's say that whenever the Space 70 00:03:09,340 --> 00:03:11,840 Bar is hit, cheesy puffs appear on the stage for the 71 00:03:11,840 --> 00:03:13,300 fish to eat. 72 00:03:13,300 --> 00:03:15,760 Before we hit the Space Bar, we'll want to keep the cheesy 73 00:03:15,760 --> 00:03:19,020 puffs hidden so that the fish can't see them. 74 00:03:19,020 --> 00:03:21,140 To do this, we'll need a couple of scripts for the 75 00:03:21,140 --> 00:03:22,750 cheesy puffs sprite. 76 00:03:22,750 --> 00:03:26,980 The first script, the green flag, will just hide the food. 77 00:03:26,980 --> 00:03:29,530 Unlike the other scripts we've written, this one won't keep 78 00:03:29,530 --> 00:03:30,560 running forever. 79 00:03:30,560 --> 00:03:33,250 It will start and finish very quickly, right when we click 80 00:03:33,250 --> 00:03:35,000 the green flag button. 81 00:03:35,000 --> 00:03:37,180 >> The next script we have will wait for the Space Bar to be 82 00:03:37,180 --> 00:03:39,590 pressed before executing. 83 00:03:39,590 --> 00:03:42,770 We can call waiting for user input "waiting" or "listening" 84 00:03:42,770 --> 00:03:43,860 for an event. 85 00:03:43,860 --> 00:03:46,750 And the code that executes when an event is received or 86 00:03:46,750 --> 00:03:50,280 heard is called event handling code. 87 00:03:50,280 --> 00:03:53,550 Our Space Bar event handler will show the cheesy puffs on 88 00:03:53,550 --> 00:03:56,330 the screen so that the fish can eat them. 89 00:03:56,330 --> 00:03:58,880 At this point, everything's looking good. 90 00:03:58,880 --> 00:04:00,990 >> The next thing we need to do is to figure out how to get 91 00:04:00,990 --> 00:04:03,570 the fish to realize that there's food to eat. 92 00:04:03,570 --> 00:04:06,030 Let's add another thread to the fish that constantly 93 00:04:06,030 --> 00:04:08,790 checks whether or not it's touching the cheesy puffs. 94 00:04:08,790 --> 00:04:11,510 We do this in a separate thread since that way we can 95 00:04:11,510 --> 00:04:13,710 constantly check for food. 96 00:04:13,710 --> 00:04:16,829 Otherwise, we'd only be able to periodically check for food 97 00:04:16,829 --> 00:04:21,180 in between gliding, turning around, waiting, or thinking. 98 00:04:21,180 --> 00:04:22,000 >> OK. 99 00:04:22,000 --> 00:04:23,785 Now let's run our Scratch program. 100 00:04:23,785 --> 00:04:26,921 As expected, the food immediately hides and the 101 00:04:26,921 --> 00:04:28,920 hungry fish swims back and forth just like before. 102 00:04:32,050 --> 00:04:35,060 When we hit the Space Bar, the cheesy puffs come into view, 103 00:04:35,060 --> 00:04:37,470 and the hungry fish says whoo. 104 00:04:37,470 --> 00:04:39,340 But wait, that's weird. 105 00:04:39,340 --> 00:04:42,150 How come the fish's "I'm hungry" thought interrupts the 106 00:04:42,150 --> 00:04:43,580 other stuff? 107 00:04:43,580 --> 00:04:45,780 This is because we didn't establish any coordination 108 00:04:45,780 --> 00:04:47,590 between the three fish scripts. 109 00:04:47,590 --> 00:04:50,610 Each is running in its own thread, oblivious to what the 110 00:04:50,610 --> 00:04:52,120 others are doing. 111 00:04:52,120 --> 00:04:54,980 Let's fix this before we move on. 112 00:04:54,980 --> 00:04:57,700 >> Coordination between threads is a tricky task since we 113 00:04:57,700 --> 00:05:00,940 don't have explicit control over when each thread runs or 114 00:05:00,940 --> 00:05:02,190 doesn't run. 115 00:05:02,190 --> 00:05:04,710 To send a message from one thread to another, we'll need 116 00:05:04,710 --> 00:05:08,300 to use a variable that we can set, or write, in one thread 117 00:05:08,300 --> 00:05:10,170 and read in the other. 118 00:05:10,170 --> 00:05:12,920 Let's create a variable called foodFound that we can set to 119 00:05:12,920 --> 00:05:15,530 true when the fish runs into the cheesy puffs. 120 00:05:15,530 --> 00:05:17,540 Well, of course, we want to make sure that we set it to 121 00:05:17,540 --> 00:05:19,240 false initially. 122 00:05:19,240 --> 00:05:22,540 Then, in the fish's thinking thread, we'll check to see if 123 00:05:22,540 --> 00:05:25,400 the fish has found food before displaying the "I'm hungry" 124 00:05:25,400 --> 00:05:26,770 thought bubble. 125 00:05:26,770 --> 00:05:29,670 >> Now, running the program again, we see that the fish 126 00:05:29,670 --> 00:05:31,580 doesn't get interrupted with thoughts of hunger when the 127 00:05:31,580 --> 00:05:33,820 cheesy puffs are out. 128 00:05:33,820 --> 00:05:36,820 The final problem we have is that the cheesy puffs don't go 129 00:05:36,820 --> 00:05:39,800 away after the fish, quote unquote, "eats" them. 130 00:05:39,800 --> 00:05:42,305 From the fish scripts, there's no easy way to hide the cheesy 131 00:05:42,305 --> 00:05:44,710 puffs, so we need to send a message to the cheesy puffs 132 00:05:44,710 --> 00:05:46,780 sprite to hide itself. 133 00:05:46,780 --> 00:05:49,550 We could do this with another variable that the cheesy puffs 134 00:05:49,550 --> 00:05:52,680 sprite has access to, as well as the fish sprite. 135 00:05:52,680 --> 00:05:55,720 >> However, there's a cleaner way to do this in this case, 136 00:05:55,720 --> 00:05:57,840 since instead of sending a message to a script that's 137 00:05:57,840 --> 00:06:00,570 somewhere in the middle of executing, we can send the 138 00:06:00,570 --> 00:06:03,710 message to a script that's waiting to start. 139 00:06:03,710 --> 00:06:07,360 We do this by having the fish broadcast an event, one we'll 140 00:06:07,360 --> 00:06:08,800 call eaten. 141 00:06:08,800 --> 00:06:11,510 Then, we'll create a script for the cheesy puffs that will 142 00:06:11,510 --> 00:06:13,030 wait for this event. 143 00:06:13,030 --> 00:06:15,560 This is similar to the Space Bar event, except that this 144 00:06:15,560 --> 00:06:19,250 time, the user's not the one directly triggering the event. 145 00:06:19,250 --> 00:06:22,800 Now all we have to do is set our foodFound variable back 146 00:06:22,800 --> 00:06:25,750 to false, and we can now give the hungry fish as many 147 00:06:25,750 --> 00:06:28,470 servings of cheesy puffs as it wants. 148 00:06:28,470 --> 00:06:30,040 >> So not too bad, right? 149 00:06:30,040 --> 00:06:33,400 In C, writing multi-threaded programs is more complicated, 150 00:06:33,400 --> 00:06:35,700 but the basics are the same. 151 00:06:35,700 --> 00:06:38,690 Anyway, I hope you have a great time building some fun 152 00:06:38,690 --> 00:06:41,030 concurrent programs in Scratch. 153 00:06:41,030 --> 00:06:42,570 My name is Nate Hardison. 154 00:06:42,570 --> 00:06:45,260 This is CS50.