简体   繁体   English

futex在这种情况下如何工作?

[英]How futex works in this case?

I have a sample code of futex. 我有一个futex的示例代码。 But i couldnt understand the code flow.... 但是我无法理解代码流。

#include <stdio.h>
#include <pthread.h>
#include <linux/futex.h>
#include <syscall.h>
#include <unistd.h>

#define NUM 50

int futex_addr;

int futex_wait(void* addr, int val1){
  return syscall(SYS_futex,&futex_addr,val1, NULL, NULL, 0);
}
int futex_wake(void* addr, int n){
  return syscall(SYS_futex, addr, FUTEX_WAKE, n, NULL, NULL, 0);
}

void* thread_f(void* par){
        int id = (int) par;

    /*go to sleep*/
    futex_addr = 0;
    futex_wait(&futex_addr,0);

        printf("Thread %d starting to work!\n",id);
        return NULL;
}

int main(){
        pthread_t threads[NUM];
        int i;

        for (i=0;i<NUM;i++){
                pthread_create(&threads[i],NULL,thread_f,(void *)i);
        }

        printf("Everyone wait...\n");
        sleep(1);
        printf("Now go!\n");
    /*wake threads*/
    futex_wake(&futex_addr,50);

    /*give the threads time to complete their tasks*/
        sleep(1);


    printf("Main is quitting...\n");
        return 0;
}

the output comes like this : 输出如下:

Everyone wait...
Now go!
Thread 0 starting to work!
Thread 1 starting to work!
Thread 2 starting to work!
Thread 3 starting to work!
Thread 4 starting to work!
Thread 5 starting to work!
Thread 6 starting to work!
Thread 7 starting to work
Thread 8 starting to work!
Thread 9 starting to work!
.
.
Main is quitting

How does actually this code is behaving?? 这段代码实际上如何运行?

what is the trigger for thread_f functions?? thread_f函数的触发器是什么?

How does wait & wake working here?? 等待和唤醒在这里如何工作?

  1. You create 50 threads and put the main thread to sleep. 您创建50个线程并使主线程进入睡眠状态。
  2. Within each thread, you set the value of futex_addr to zero (redundantly). 在每个线程中,将futex_addr的值设置为零(冗余)。
  3. You call futex_wait with the address of that value, and a value parameter of zero. 您使用该值的地址和值为零的值调用futex_wait That means "block, if the value I point to is (still) really zero" . 这意味着“如果我指向的值仍然(真的)为零,则阻止”
  4. sys_futex checks that the value at &futex_addr is really zero, which is the condition for blocking your thread (that is important for the correct operability of the syscall, otherwise futex_wake would have to block alike NtReleaseKeyedEvent under Windows). sys_futex检查&futex_addr的值是否确实为零,这是阻塞线程的条件(这对于syscall的正确可操作性很重要,否则futex_wake必须像Windows下一样NtReleaseKeyedEvent )。 Of course the value is zero, that's all any thread has ever written to it, so your thread blocks. 当然,该值为零,这是所有线程已写入的所有值,因此您的线程将阻塞。
  5. The main thread eventually returns from sleep and calls futex_wake with a parameter of 50, which means "wake (up to) 50 threads that are waiting on &futex_addr " . 主线程最终从sleep返回,并使用参数50调用futex_wake ,这意味着“唤醒(最多)50个正在&futex_addr上等待的线程” So all your 50 threads wake up in one big thundering herd. 这样一来,您所有的50条线就会在一大群雷声中醒来。
  6. Each thread writes a message to stdout (without synchronization, so you might see garbled output) and exits. 每个线程都会向stdout写一条消息(没有同步,因此您可能会看到乱码)并退出。
  7. The main thread exits as well, without joining threads or synchronizing, but due to the second call to sleep , chances are that it will "work fine" without evil things happening, anyway (not that it's a good thing to write code like this!). 主线程也退出了,没有加入线程或没有同步,但是由于第二次调用sleep ,很有可能它会“正常工作”,无论如何也不会发生邪恶的事情(写这样的代码不是一件好事! )。

Note that this method of waking N threads works , but is discouraged (much like using futex in the first place is discouraged, too). 请注意,这种唤醒N线程的方法有效 ,但是不建议使用(就像不建议首先使用futex一样)。 Typically you want to wake exactly one thread (use 1 ), or all threads (use INT_MAX ). 通常,您只想唤醒一个线程(使用1 )或所有线程(使用INT_MAX )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM