What are Race Conditions?

Поделиться
HTML-код
  • Опубликовано: 7 июн 2024
  • Source code can be found here:
    code-vault.net/lesson/18ec194...
    ===== Support us through our store =====
    code-vault.net/shop
    ===== Check out our website =====
    code-vault.net
    ===== Check out our Discord server =====
    discord.code-vault.net

Комментарии • 116

  • @peteremmanuel8557
    @peteremmanuel8557 2 года назад +63

    Never seen race conditions broken down pragmatically like this in my life. I was awestruck when you took it to the assembly level. I couldn't believe my eyes. Thanks for this great video boss.

    • @tomatte99
      @tomatte99 Год назад +1

      this is pure preciosity

  • @32Praful
    @32Praful 3 года назад +71

    The OS subject should be taught like this, instead of whiteboarding.
    This is to the point. Thanks!

    • @jardondiego
      @jardondiego 2 года назад +1

      you just don't pay attention to your teacher, give them some credit

    • @tomatte99
      @tomatte99 Год назад +3

      @@jardondiego whiteboarding is full of abstractions, this is showing verything under the hood, so more powerful for learning

  • @thexoxoboyz
    @thexoxoboyz 2 года назад +1

    I get so happy when I search up an OS topic and your video pops up because I know for a fact Ill understand it. Amazing work man!!

  • @animeprogrammer
    @animeprogrammer 3 года назад +7

    Thanks for putting efforts for all of us! really love your content, to the point yet detailed.

  • @Jonathan-ru9zl
    @Jonathan-ru9zl 6 месяцев назад +2

    4:13 you nailed it. This core explanation is what most of the tutorials are missing.

  • @tehuanmelo
    @tehuanmelo Год назад +1

    First time getting in contact with threads, you make the concept so easy to understand. Thanks a lot for the content!

  • @oliveryt7168
    @oliveryt7168 3 года назад +11

    As somebody who is just at the beginner level of C I can say, you produce the most "family friendly" (all the "horrors" of C compiled into nice, easy to follow explanations) videos on C. Well done!

    • @sagivalia5041
      @sagivalia5041 Год назад

      C imo is the least "horror" inducing language out there
      C# and Java has a whole "horror" procedure just to write to console.
      Ofc, if you get into obfsucated C, it will get bad visually

  • @aymaneechafii615
    @aymaneechafii615 Год назад +5

    Those from 42 Network, give it a like and good luck with the philosophers project! 🙏

  • @mridhop
    @mridhop 2 года назад

    Thank you very much for all of your videos about processes and threads

  • @FrodosBeutel
    @FrodosBeutel 2 года назад +19

    if professors could explain like you everyone would pass

    • @kayakMike1000
      @kayakMike1000 Год назад +1

      I don't really think so. Some people don't even go to all their classes.

    • @AlFredo-sx2yy
      @AlFredo-sx2yy 9 месяцев назад

      @@kayakMike1000 Those are either the people that end up passing with the highest grades or the slackers that wont make it through. There is no in between for people who dont go to class. At least in modern times. Back when teachers actually taught and didnt just play a youtube video in class as a form of "teaching", good students would actually attend all classes. But times have changed. For the worse, if you ask me. Now spending your time learning on your own is the best way to go, sometimes even the only way to go.

  • @makyxyz3375
    @makyxyz3375 Год назад

    Wow, impressive clear and really fast to understand the concept. Thank you!

  • @0x42NaN
    @0x42NaN 7 месяцев назад

    Thread-safe-ness is a really important topic :) amazing explanation - enjoyed it, even though i already knew about it. never seen it in assembly though. loved that part, helps understanding the whole picture if you're not into it.

  • @ndf782
    @ndf782 3 месяца назад

    Your classes are amazing! All of them! Just one thing, I think that when you say race condition, the correct term is data race. Cheers!

  • @tomatte99
    @tomatte99 Год назад

    thank you very much, it was amazing to see how the assembly do things

  • @benjangel
    @benjangel 24 дня назад

    That's a very eye opening presentation my master. You're hundred times better at teaching than my professor. I very appreciate of all the work you made. Thank you so much master. 😘😘

  • @patrikhyll4301
    @patrikhyll4301 Год назад +1

    Dude, this is great stuff! Excellent explanation skills

  • @zaabimahdi
    @zaabimahdi 3 года назад

    Nice to see you back !

  • @ragd4L
    @ragd4L 3 года назад +14

    Beautifully explained!

  • @novigradmerchant2400
    @novigradmerchant2400 3 года назад +3

    Thx for video and please keep thread video series very detailed because on youtube there's no detailed playlist, please go into deep, my friend. And thank you sooo much. Keep it up 😃

    • @CodeVault
      @CodeVault  3 года назад +5

      There's a lot to cover (condition variables, barriers, producer-consumer problem etc. + examples/exercises) so expect at least ~20 videos on the topic. If you have anything specific in mind please tell me!

    • @novigradmerchant2400
      @novigradmerchant2400 3 года назад +1

      @@CodeVault you're breathtaking! Thank you so much 😘

  • @dinispetrukha4382
    @dinispetrukha4382 2 месяца назад

    you are amazing bro! Big brain + good teacher. No words, how this is free

  • @scottalexgray
    @scottalexgray Год назад +1

    It's also important to note the case when each thread reads the same value from memory, increments it and writes it back to memory, effectively "removing" one of the thread operations. I think this is more likely to happen than one thread being allowed to run multiple times before allowing the next to run and undo the work of the first thread

  • @lavredisgoume
    @lavredisgoume 2 года назад

    Very clear explanation and a great course in total!

  • @andrehernandez5798
    @andrehernandez5798 2 года назад +1

    Ahahhaha he's so funny! It's charming to watch your videos. You have a very awesome vibe!

  • @manuelavendano3891
    @manuelavendano3891 2 года назад

    Outstanding explanation mate

  • @brettchallice8132
    @brettchallice8132 4 месяца назад

    this video is so clear and well explained . thank you !

  • @srikanthblv7171
    @srikanthblv7171 Год назад

    Thanks for the amazing explanation. @ 11:35, you said one thread would be executed first, after which the second thread would be executed. But in the first video of this series, you said that threads are implemented in parallel and not one after the other. You even demonstrated this using sleep(3). Please clarify.

    • @CodeVault
      @CodeVault  Год назад

      Basically in the time it takes to create the next thread, the first thread finishes its execution. While it's true that threads run in parallel, the first threads that are created get a head-start

  • @AndreFerreira-jv3qy
    @AndreFerreira-jv3qy 19 дней назад

    Thank you man this was really helpfull you are a great!

  • @adhamadel8937
    @adhamadel8937 2 года назад

    You are Genius, i am cannot speak english very well but i want to say to you very very very thank you about this amazing explanation

  • @elkhoukhi
    @elkhoukhi 3 года назад +1

    what a beautiful simply put explanation!

  • @kosmonautofficial296
    @kosmonautofficial296 Год назад

    Great video! Thanks for the great explanation. I mainly use Python but this was very similar

    • @CodeVault
      @CodeVault  Год назад

      Definitely. The threads tutorial could be used in any language as long as you can translate the higher level concepts like thread, mutex, barrier etc.

  • @wassimbardusch8090
    @wassimbardusch8090 Год назад

    Hey,
    First thing thank you very much for your Videos, could you name the IDE, which do you use ? and on which Operating system do you work ?
    Ich hope of an answer :)

    • @CodeVault
      @CodeVault  Год назад +1

      I'm using Visual Studio Code that is remotely connected to a Debian machine. The videos are recorded on Windows

  • @snowballwang285
    @snowballwang285 Год назад +1

    Can I say race condition is more likely to occur when setting loop to 1 million because it takes longer time to finish the execution for each threads? In other words, thread p2 will be created after thread p1. But it is up to OS scheduler to decide which thread to run and how long it will run for one scheduling time slot. So if the execution time is very long and need more than just one scheduling slots, it is much easier to threads to interleave with each other. Is my understanding correct? Anyway, thanks for your great explanation in the video!

    • @CodeVault
      @CodeVault  Год назад +1

      Yea, that is true. Similarly, if you have threads that execute in a short amount of time, race conditions occur less often. Also, if the instruction(s) are finished in one CPU cycle there's no way for race conditions to occur. This is the reason why semaphores don't create race conditions when you call sem_wait and sem_post

  • @mikicerise6250
    @mikicerise6250 3 года назад +2

    Awesome stuff! One thing I don't get is how each thread's register would hold on to the value it originally read in a single CPU. If both threads are run on separate CPUs then it makes sense, but if they are both on the same CPU then surely the other thread will overwrite eax with its own value unless there are additional instructions to push the original value to another register or to memory to save it? Does the kernel do this automatically when it tells the thread to 'take a break'? :)

    • @CodeVault
      @CodeVault  3 года назад +4

      Yes, the kernel does it automatically with something called "context switching". Basically all threads/processes get some CPU time if they are running at the same time. So instead of your while(true) loop blocking the whole computer (assuming you have 1 core and 1 CPU) it would allocate some execution time to that process and then context switch to another process that needs to execute and so on and so forth.

    • @ryanskelton8268
      @ryanskelton8268 2 года назад

      I could be wrong, however a thread shares the same memory from the main. Except the program counter, stack and its own set of registers. Therefore it seems that its writing to the same register, however a different set of registers which loads between context switching of threads/processes.

  • @tatianak3806
    @tatianak3806 2 года назад +1

    Thank you a lot for the video! Great as always :) Could you please explain why there is the same number (23) at "read mails" and "increment" steps? I assumed the incrementation step result is 24 as well as the "write" step

    • @CodeVault
      @CodeVault  2 года назад +5

      Ahh, that is because this mail++ operation we do has multiple steps in the CPU itself:
      1) Read the "mail" value from memory to the CPU register
      2) Increment the value stored in that CPU register
      3) Write whatever is in that CPU register to the address where "mail" is stored
      What I am showing in that diagram is always the actual value of "mail" in the memory (not in the CPU), hence why it's still 23 in the increment row

    • @ndf782
      @ndf782 3 месяца назад

      My only doubt is if in the cpu register is 30 in the increment phase, so it should increments and turn in 31. How is 30 in the cpu register and you increment to 24?
      By the way, thanks a lot for all your videos!! And I miss new videos. You are the best!

  • @daniloterzic3283
    @daniloterzic3283 2 года назад

    Stunning explanation!

  • @daoudbrahim9084
    @daoudbrahim9084 3 года назад +5

    thank you so much brother ❤

  • @sony1979iq
    @sony1979iq 2 года назад

    as i heard from you that with threading that threads should go in parallel, as you show in a previous video example. Isnt race condition breaking the parallel thing here? very nice explanation

    • @CodeVault
      @CodeVault  2 года назад

      They don't always have to go in parallel. Yes, ideally is to have threads that always work in parallel but sometimes you need to prevent situations like these from happening.

  • @a0b9180
    @a0b9180 2 года назад +1

    Around 8:10 time, if for T2, the increment (register) value in the CPU is 30, then shouldn't it work with that register value and write 31 to the memory? How will it increment 23 to 24, if the register value has been 30?
    I also googled and each thread will have its own register and stack, so T2 will not have 30. Any thoughts?

    • @CodeVault
      @CodeVault  2 года назад +1

      That diagram I showed seems to be confusing. Should've done a better job but, what is in each cell is actually the value that is inside the variable at the point of execution (not necessarily what each thread sees). I hope that clears up the confusion

  • @ddddanny3211
    @ddddanny3211 Год назад

    You should be extremely proud of yourself. You explained it beautifully.

  • @zxuiji
    @zxuiji 2 года назад +2

    It occurs to me race conditions could be used to generate truly random numbers, something like:
    void* rng_thread( void *ud )
    {
    while ( 1 )
    {
    rng_seed++;
    pthread_yield();
    }
    }
    The pthread_yield() is just there to give the system a chance to kill the app &/or thread

    • @CodeVault
      @CodeVault  2 года назад +1

      They won't truly be random but they are probably going to depend a lot on the environment it's running on (for example what other processes are running and whatnot)

    • @zxuiji
      @zxuiji 2 года назад

      @@CodeVault Compared to pseudo random numbers generated by say the LSR somethinf method (forgot the name) it is definetly less predictable, although this method is likely only of use in games where some things should be harder to predict, like enemy actions

    • @CodeVault
      @CodeVault  2 года назад +2

      This reminds of that lava lamp wall that is recorded by a camera which is used to generate random numbers. Usually pseudo-random numbers are good enough but, if you ever need a truly random number, I guess using something from real life and encoding it into a number is probably the closest we can get to true randomness

  • @kayakMike1000
    @kayakMike1000 Год назад +1

    You need to make that global variable volatile and make sure your compiler doesn't optimize your loop.

  • @yashagrawal1663
    @yashagrawal1663 8 месяцев назад

    @codeVault Hello sir could you justify this statement. If threads run parallely then for the mail variable gets incremented by the two threads at the same time.
    So the net increase in the count should be 1. As both the threads increment the mails variable at same time.

    • @CodeVault
      @CodeVault  8 месяцев назад

      Yes. Basically both threads read the same number (say, 45) and they both individually increment this number by 1 to 46. Then, they both write to that place in memory that 46. So even though 2 increments happened, we can only see one

  • @laskdjf3880
    @laskdjf3880 Месяц назад +1

    this is amazing :)

  • @ahmetkarakartal9563
    @ahmetkarakartal9563 Год назад

    wow, what a lesson, thank you so much

  • @TehObLiVioUs
    @TehObLiVioUs 2 года назад +1

    Fantastic video totally understand now

  • @jokerTrickzzZ
    @jokerTrickzzZ 2 года назад +1

    in your example at 8:20 the increment for t2 is 30. Doesn't it have to be 23, because each Thread calls the routine function at the start, which means that they both create a new function call which is put on the stack? So the iteration of the for loop is in both threads 1000000 times or am I wrong? The problem is that for example thread 2 and thread 1 manipulate the variable mails at the same time which can cause the shown problems. So my question is, does each thread iterates the for loop exactly 1000000 times in your example.

    • @CodeVault
      @CodeVault  2 года назад +2

      Yes, each thread loops exactly 1000000 times.
      I guess that explanation was a bit wrong as the value should represent what each thread has read, not what the actual value is in variable. I should've put 23 there instead of 30, you're right.

    • @jokerTrickzzZ
      @jokerTrickzzZ 2 года назад +1

      @@CodeVault thank you very much :) your videos are the best they helped me a lot!

  • @armageddovig
    @armageddovig Год назад

    @CodeVault :
    @10:18 : line 26, ;at line of the L2 command : add1 $1, -4(%rbp)
    This add 1 to the memory address of (rbp - 4)
    -> What is the point of this ?
    Thanks in advance.

    • @CodeVault
      @CodeVault  Год назад

      That's just incrementing the i variable (from the for loop). Notice at the top how -4(%rbp) is initialized with 0 and at the bottom how it is compared with our number of iterations

  • @attituderecord7589
    @attituderecord7589 2 года назад

    You explain soooo well

  • @user-fe3qs5gm8m
    @user-fe3qs5gm8m 2 года назад

    Thank you! clearly explained

  • @kavinashokan5692
    @kavinashokan5692 2 года назад

    according to your code there are 2 pthreads, with small numbers in mail variable increment both the thread excecuted sequentially (first thread 1 and after that thread 2). when you increased mail increment to 1000000 does thread one and thread 2 excecutes concurrently ? if they excecute concurrently, will this concurrent excecution will occur on single core cpu's ? or this concurrent excucution will happen only on cpu's with dual or more cores ? anyone please explain

    • @CodeVault
      @CodeVault  2 года назад +1

      The concurrent execution can happen on both single core and multi core CPUs. Operating systems use something called "context switching" (you can google the term to find out more). Basically it's how multiple processes run simultaneously in an OS even with single core CPUs

    • @kavinashokan5692
      @kavinashokan5692 2 года назад

      @@CodeVault thank you brother

  • @malplena2888
    @malplena2888 Год назад

    Thank you so much!

  • @mohamedalichabani6775
    @mohamedalichabani6775 Год назад

    What if I'm working with threads and I get an unexpected value just like in the mailbox example. How can I tell if the result is due to a race condition or to an overflow ?

    • @CodeVault
      @CodeVault  Год назад +1

      That's the issue with race conditions. It's difficult to tell when they happen. For overflows you could maybe check for upper or lower bounds. For race conditions... I'm not aware of any way you can detect them (maybe with a checksum of sorts?)

    • @albanec4702
      @albanec4702 8 месяцев назад

      overflow will give excact same result within excact same input
      race conditions are much chaoticalier and`ll result different output each time

  • @enesb4797
    @enesb4797 2 года назад +1

    How did you open assembly page? I can't open it.

    • @CodeVault
      @CodeVault  2 года назад +1

      The shortcut I used there is CTRL + P (although you should also find the main.s file near your main.c file in the same folder)

    • @enesb4797
      @enesb4797 2 года назад +1

      @@CodeVault Yes! I found .s file near it! Thank you!

  • @iloveukraine-subscribe1kgo822
    @iloveukraine-subscribe1kgo822 3 года назад

    8:45 I didn't understand the issue. For all the time the value of global variable stays the same if it looks in the memory. Then why did it change, from 30 to 24?

    • @iloveukraine-subscribe1kgo822
      @iloveukraine-subscribe1kgo822 3 года назад +1

      Sorry.. understood, didn't listen the word register.

    • @mikicerise6250
      @mikicerise6250 3 года назад

      @@iloveukraine-subscribe1kgo822 Didn't register? Sorry... somebody had to do it... ;)

  • @asheeshmathur
    @asheeshmathur 2 года назад

    Doing Wonderful Job ...that to for free. Service to humanity, sure you will be suitably rewarded.

  • @pbmodig
    @pbmodig 3 года назад

    A absolute king.

  • @pielevlad8090
    @pielevlad8090 2 месяца назад

    congrats!

  • @shivanichopra1
    @shivanichopra1 Год назад

    Why didn’t we created separate routine for both the threads and added a sleep in one thread to simulate one thread occupied while other is executing longer
    Agree that race condition is not guaranteed but the probability will increase right?

    • @CodeVault
      @CodeVault  Год назад

      I think it might decrease since the overlap of execution time will be smaller

  • @maybeyesterday
    @maybeyesterday 2 года назад

    A 100 iterations didnt work because C compiler optimization turns loops where there is only one number incremented a couple times into "non loops", so a loop where x is inc. 10 times will be turned into x += 10 by the compiler. Thats why there were no race conditions with small numbers. Not because it takes too long or too short or smth ... .This optimisation stops at a certain number.

    • @CodeVault
      @CodeVault  2 года назад +1

      Ahh, that makes sense. Should've looked at the assembly code more carefully then. Thanks for clarifying!

  • @Aina-ud8pk
    @Aina-ud8pk Месяц назад

    Just incase you forgot, you are the GOAT!!

  • @dsalgos
    @dsalgos 2 месяца назад +1

    I feel the frustration when race condition did not occur despite of increasing the value to 10000

    • @CodeVault
      @CodeVault  2 месяца назад +1

      The CPUs are too fast these days haha

  • @sepgh2216
    @sepgh2216 2 месяца назад

    Let me guess... you were also surprised you had to go up till million to create the race condition :D I honestly expected it much sooner! I don't know if its C being good at this or what but I arrived at race conditions in other languages way sooner. I guess afterall it involved "luck" tho a little. You could even see 1 instead of 2 without a loop?

    • @sepgh2216
      @sepgh2216 2 месяца назад

      Commented it too soon. You explained it in the end. Amazing!

  • @dealvin
    @dealvin 2 года назад

    but the pthread_exit() is important ? or not?

    • @CodeVault
      @CodeVault  2 года назад

      Not really. It's optional. pthread_exit is called automatically when you return anything from the thread function

    • @dealvin
      @dealvin 2 года назад

      @@CodeVault thank you, hero

  • @abhaygaikwad6251
    @abhaygaikwad6251 2 года назад

    understood

  • @lonerinthecorner1839
    @lonerinthecorner1839 Год назад

    2 words. Thank you.

  • @evgeniiorlov1223
    @evgeniiorlov1223 3 года назад

    jesus!
    I love you!

  • @zxuiji
    @zxuiji 2 года назад

    Dude, you could give a simpler to understand explanation for noobs:
    Think of each thread as a person, they each copy information from a document, they then modify that information and overwrite the old information, each person starts at different times but over time their timings align such that when one person copies information it is before the other person has updated the information with their own modified state meaning the information they modify is out of date and will cause the other person to get older information after they overwrite the documents information, the timing of the overwrites is the race condition

    • @CodeVault
      @CodeVault  2 года назад

      Yea, that's a great example! Thanks for the feedback. I'll try to use this example from now on for race conditions

  • @ReactCode0
    @ReactCode0 8 месяцев назад

    sir one video create on setup phtread in vs code

    • @CodeVault
      @CodeVault  8 месяцев назад +1

      Add "-pthread" to your build.json args list and it should compile without issues if you're on a Unix system

    • @ReactCode0
      @ReactCode0 8 месяцев назад +1

      @@CodeVault i am in Window

    • @CodeVault
      @CodeVault  8 месяцев назад

      @@ReactCode0 pthreads are unix-only. You could try running WSL with Ubuntu and compile and run your project there

    • @ReactCode0
      @ReactCode0 8 месяцев назад

      @@CodeVault thanks sir

  • @undeadpresident
    @undeadpresident Год назад

    something to do with "white privilege" and colonialism?

    • @CodeVault
      @CodeVault  Год назад +1

      No. It's about issues regarding multiple threads accessing (and modifying) the same address in the computer memory

    • @undeadpresident
      @undeadpresident Год назад

      @@CodeVault Well then, it sounds like something that would be good to know!