Как Futex работает в моем коде?
Я вижу беспорядочный вывод из моего кода futex.
Вот мой код,
#include <stdio.h>
#include <pthread.h>
#include <linux/futex.h>
#include <syscall.h>
#include <unistd.h>
#include <limits.h>
#include <time.h>
#include <sys/time.h>
#define NUM 15
int futex_addr=1;
int futex_wait(int* addr, int val1){
if( --(*addr)==0)
{
printf(" after dec :futex : %d\n",futex_addr);
return 0;
}
else
{
*addr==-1;
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;*/
//printf("before wait, futex : %d\n",futex_addr);
futex_wait(&futex_addr,0);
printf("after wait, futex : %d\n",futex_addr);
/*if((--futex_addr)!=0)
{
futex_addr=-1;
futex_wait(&futex_addr,0);
}
else
{*/
printf("Thread %d starting to work!\n",id);
for (int i=0; i<30000; i++)
{
//printf(" Thread %d is in loop for %dth time\n",id,i);
}
printf(" thread %d finished\n",id);
if(++futex_addr != 1)
{
futex_addr=1;
futex_wake(&futex_addr,INT_MAX);
}
return NULL;
/*}*/
}
int main(){
pthread_t threads[NUM];
int i;
struct timeval start,end,elapsed;
gettimeofday(&start, NULL);
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,INT_MAX);
/*give the threads time to complete their tasks*/
//sleep(18);
for (int i = 0; i < NUM; i++) {
pthread_join(threads[i], NULL);
}
printf("Main is quitting...\n");
gettimeofday(&end, NULL);
timersub(&end, &start, &elapsed);
printf("secs: %ld.%06ld seconds\n msecs: %ld.%06ld seconds\n",
(long)(elapsed.tv_sec), (long)(elapsed.tv_usec));
return 0;
}
выход:
after dec :futex : 0
after wait, futex : 0
Thread 0 starting to work!
thread 0 finished
after dec :futex : 0
after wait, futex : 0
Thread 1 starting to work!
thread 1 finished
after dec :futex : 0
after wait, futex : 0
Thread 2 starting to work!
after wait, futex : -2
Thread 4 starting to work!
thread 4 finished
after wait, futex : -3
Thread 5 starting to work!
thread 2 finished
thread 5 finished
after wait, futex : -4
Thread 6 starting to work!
thread 6 finished
after wait, futex : -5
Thread 7 starting to work!
thread 7 finished
after wait, futex : -6
Thread 8 starting to work!
thread 8 finished
after wait, futex : -7
Thread 9 starting to work!
thread 9 finished
after wait, futex : -8
Thread 10 starting to work!
thread 10 finished
after wait, futex : -9
Thread 11 starting to work!
thread 11 finished
after wait, futex : -10
Thread 12 starting to work!
thread 12 finished
after wait, futex : -11
Thread 13 starting to work!
thread 13 finished
after wait, futex : -12
after wait, futex : -1
Thread 3 starting to work!
thread 3 finished
Thread 14 starting to work!
thread 14 finished
Main is quitting...
secs: 1.001813 seconds
msecs: 14.134513484 seconds
Проблема здесь в том, что перед тем, как поток 2 освободит futex, другой поток получит его (если вы видите в выводе tht).
Thread 2 starting to work!
after wait, futex : -2
Thread 4 starting to work!
thread 4 finished
after wait, futex : -3
Thread 5 starting to work!
thread 2 finished
Так почему же так происходит? когда поток 2 использует futex, как он передается потоку 4? Есть ли какой-либо недостаток в коде?