我有一个futex的示例代码。 但我无法理解代码流......
#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;
}
输出如下:
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
这段代码实际上是如何表现的?
thread_f函数的触发器是什么?
等待&amp;醒来在这里工作??
答案 0 :(得分:2)
futex_addr
的值设置为零(冗余)。futex_wait
。这意味着“阻止,如果我指向的值是(仍然)真的为零”。sys_futex
检查&futex_addr
处的值是否为零,这是阻塞线程的条件(这对于系统调用的正确可操作性很重要,否则futex_wake
会有在Windows下阻止NtReleaseKeyedEvent
。当然值为零,这就是任何线程都写入它的所有内容,所以你的线程阻塞。sleep
返回并使用参数50调用futex_wake
,这意味着“唤醒(最多)50个等待&futex_addr
的线程” 。所以你的所有50个线程都在一个大雷鸣般的群体中醒来。stdout
写一条消息(没有同步,因此您可能会看到乱码输出)并退出。sleep
,很可能它会“正常工作”而不会发生任何恶意事件(不是说它是好的)写这样的代码的事情!)。请注意,这种唤醒N
线程的方法,但不鼓励(非常不喜欢首先使用futex
)。通常,您希望仅唤醒一个线程(使用1
)或所有线程(使用INT_MAX
)。