Practical example to barriers (pthread_barrier)

Поделиться
HTML-код
  • Опубликовано: 2 июн 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

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

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

    You are an amazing teacher. Love the way you simplify all such complex topics. Please make more videos... Like these on ompi and cuda as soon possible. Thanks a lot. May God bless you. 🤗

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

      I'll look into those too! Thanks!

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

      Thankyou, I really need help with this as soon as posible

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

    thank you for the help. You are an amazing teacher !

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

    Amazing video and very well taught! Thank you!

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

    God bless you! ☺Thanks for the videos 👍

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

    You are just next to amazing👏👏👏

  • @planetis-m6066
    @planetis-m6066 3 года назад +1

    That was great thank you!

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

    Great video, thanks.

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

    excellent tutorials

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

    Very useful!

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

    Wish you were on youtube back when I was in college.

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

    Thank you

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

    Hi codevault, A question regarding the last parameter of barrier initialization.
    Would waiting on these barrier basically do nothing?
    pthread_barrier_init(&our_barrier1,NULL,0);
    pthread_barrier_init(&our_barrier2,NULL,1);
    Is there any reason to use 0 or 1?

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

      I don't know of a reason to use any of those. Barrier with count 0 is undefined behaviour, so not supported by the standard. Barrier with count 1... will work as expected... but would be useless

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

      @@CodeVault agreed. appreciate it

  • @Sandy-mv3tl
    @Sandy-mv3tl 2 года назад +2

    So if I am understanding this correctly, when you wanna know if a single thread has completed its execution of a particular code segment, you use condition variables to signal or broadcast, but when you wanna know if multiple threads has completed their execution of a common code segment, you use barriers?

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

      Yes, you could put it that way. Usually a condition variables's signal or broadcast signals to other threads that the condition they are checking *might* have changed. Whereas barriers are just as you explained.

  • @omarelnaggar9940
    @omarelnaggar9940 Год назад +2

    there is something that I'm not understanding quite well,
    I understood that the barrier makes the threads to wait until the barrier count of threads is satisfied,
    but when u initialized the barrier with Thread_num+1 in main function and then used it in the roll_dice function
    there are just 8 threads are going to enter the roll_dice function and wait at the barrier , but the barrier count is 9
    so we have one last thread to satisfy the barrier count
    u said that main is the last thread but how the main is gonna enter the roll_dice function and go through the barrier ?
    I didn't understand this part quite well , if u could explain it , I appreciate it.
    and thanks alot for your content, it's just amazing ❤

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

      There are 9 threads in this example. 8 are the ones created by us using pthread_create and the 9th one is the main thread we get when executing the program. To affect the barrier we don't have to call roll_dice, we just need to call one of the pthread_barrier functions in the main function. That's what we do in the example

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

      In the previous video of introduction to barriers when you initialised the barrier with 3, and created 2 threads, it did not work and kept waiting at the barrier. but by this logic it should have worked because there will be total three threads( two created by us using pthread_create and one main).
      Can you pls explain this @@CodeVault

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

      @@vivekdhanda5540 The program is calling pthread_barrier_wait with only the 2 threads that we created. You will notice that the main thread doesn't call that function. That's why it's not crossing the barrier

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

      ohh ok, thanks for the reply @@CodeVault

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

    10:00 Also we could do calculation after "pthread_join" for loop. But I understand the problem. The real case could not be that simple.

  • @titorrito-productions7437
    @titorrito-productions7437 2 года назад

    Dear CodeVault, Im trying to compile using the pthread library and its having trouble to recognize pthread_barrier_t. And in man pthread barriers don't show up. So where do they come from? Thanks in advanced (;

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

      Hmm, never encountered this before. A quick google search and here should be your solution: stackoverflow.com/questions/61647896/unknown-type-name-pthread-barrier-t

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

    Man you are better than my college profesor.
    Why can not we use the barrierRolledDice again? Why do we have to create another one?
    Also would broadcast do the work?

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

      You can. But it makes for more legible code. People always forget to give meaningful names to mutexes, condition variables and other synchronization objects which becomes a big issue on larger projects.
      Broadcast with condition variables? It might be more complicated because, when broadcasting, you're not guaranteed that ALL threads got to the wait. With barriers, that is guaranteed.

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

    Wouldn't only using the 2nd barrier (barrierCalculated) work for us? Cause shouldn't we just have a barrier in the main thread when we have calculated what is the win condition and can then let threads check if they won. I ran the code and it works but if there is something else that might be happening do tell.

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

      No, that's not right, because, if you only have 1 barrier, the other threads could pass through that barrier AND check their status BEFORE the main thread is able to calculate the results

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

      @@CodeVault aah true makes sense. Thanks for the reply.

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

    Can we implement this example with the signals?

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

      Signals aren't really meant to be used this way. They are a really low level inter-process messaging system used to send "critical" and immediately actionable tasks. You could implement this using pipes though.

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

      @@CodeVault hmmm thank you

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

    At 11:10, why can't we use semaphores for this purpose?

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

      Because with barriers there's no thread that says "ok, you can go forward". It's all automatic based on how many threads are waiting at that spot. You can probably do the same thing with semaphores, but it's gonna take more than just replacing the barriers with semaphores

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

    Thank you for example. Can you please show some examples for linux io_uring. Io_uring makes sync call async.

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

    Can''t we use also condition variable broadcast instead of barrierCalculated?

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

      No, because, it's not guaranteed that, when you broadcast, ALL the threads were waiting at the condition variable's wait

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

      @@CodeVault Oh, it seemed to me that after barrier named "barrierRolledDice" they are all on the same page and just have to wait until main thread will calculate result, and instead of "barrierCalculated" there could be a broadcast condition variable. But the trick probably is that it is possible that main thread will calculate the result, broadcast condition, while not all remaining threads started waiting for that signal, as thread execution sequence is random. Is this a right understanding?

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

      Exactly. With barriers, ALL threads have to wait until they continue. Of course, I think you can do it without barriers too... although you can't just replace the barriers with condition variables. I'll let you think about it!

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

    Thanks for your incredible videos. Would you help me answer the above questions:
    In ex1.c (6.1), which of the following properties achieved:
    (1) Mutual exclusion but not progress
    (2) Progress but not mutual exclusion
    (3) Neither mutual exclusion nor progress
    (4) Both mutual exclusion and progress
    Please explain?
    1.2
    To which arguments (in 6.1) is correct and which does not:
    (1) always exits. when threads = 2 or threads 2
    for the above code:
    int S1 = 0;
    int S2 = 0;
    int x = 0;
    int run = 1;
    void Producer(void) {
    while(run) {
    while (S1 == S2);
    x++;
    __sync_synchronize();
    S1 = S2;
    __sync_synchronize();
    }
    }
    void Consumer(void) {
    while(run) {
    while (S1 != S2);
    x--;
    __sync_synchronize();
    S1 = !S2;
    __sync_synchronize();
    }
    }
    void* Worker(void *func) {
    long func_id = (long)func & 0x1;
    printf("%s %d
    ",__func__, (int)func_id);
    switch (func_id) {
    case 0:
    Producer();
    break;
    case 1:
    Consumer();
    break;
    }
    return NULL;
    }
    int main(int argc, char *argv[]) {
    pthread_t t[argc];
    pthread_attr_t at;
    cpu_set_t cpuset;
    int threads;
    int i;
    #define MAX_PROCESSORS 4 // Minimal processors is 2.
    threads = argc > 1 ? (( atoi(argv[1]) < 4) ? atoi(argv[1]):
    MAX_PROCESSORS ) : 1;
    for (i = 0;i < threads; i++){
    CPU_ZERO(&cpuset);
    CPU_SET(i, &cpuset);
    pthread_attr_init(&at);
    pthread_attr_setaffinity_np(&at, sizeof(cpuset), &cpuset);
    if (pthread_create(&t[i], &at , Worker, (void *) (long)i) ) {
    perror("pthread create 1 error
    "); }
    }
    do {
    sleep(1);
    } while(x < 0);
    run = 0;
    void *val;
    for(i = 0; i < threads; i++)
    pthread_join(t[i], &val);
    printf("x=%d
    ", x);
    }

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

      Sorry, I'm not here to solve your homework. First try answering the questions yourself