0

我正在尝试使用futex系统调用来同步两个独立的 c 程序。progA创建多个线程并从每个线程调用futex_test。我试图确保一次只progA运行一个线程futex_test

我的方法,因为我想不出一种方法来初始化这两个程序之间共享的任何全局变量,所以progA创建并写入1(available)共享内存。并且在futex_test从同一内存中调用读取时,写入0(unavailable)并调用FUTEX_WAIT系统调用。完成后,它会写入1共享内存并调用FUTEX_WAKE.

但是,它不起作用。我理解这是一个错误的逻辑。知道如何进行这项工作吗?

注意:我不想对“progA”做任何改变。我只能对futex_test

程序A.c

typedef struct file{
    int pid;
} file_entry;

pthread_t tid[5];
int counter=0;


void write_1_mem(){

    int shmid;
    int n;
    file_entry *entries;

    if ((shmid = shmget(20541, sizeof(file_entry) + 256, IPC_CREAT | 0666)) == -1) {
        printf("problem3");
        exit(2);
    }

    entries = (file_entry *) shmat(shmid, 0, 0);
    if (entries == NULL ) {
        printf("problem4");
        exit(2);
    }

    int pidD = 1;
    entries->pid  = pidD;
    shmdt(&shmid);
}



void* trythis(void* arg){
    printf("Thread %d created\n",counter);  
    system("./futex_test");
    printf("Thread %d finished\n",counter);
    return NULL;
}



int main(){
    int i = 0;
    int error;
    int k=0;

    write_1_mem();

    while (i < 5) {
        counter=i;         
        error = pthread_create(&(tid[i]),NULL,&trythis, NULL);
        if (error != 0)
            printf("\nThread can't be created :[%s]",strerror(error));
        i++;
    
    }

    for (k=0;k<5;k++){
        pthread_join(tid[k], NULL);
    }

    return 0;
}

futex_test.c

typedef struct file{
    int pid;
} file_entry;

// Global variable
int shmid;
file_entry *entries;
static int *ftex;


//system call
static int futex(int *uaddr, int futex_op, int val, const struct timespce *timeout, int *uaddr2, int val3 ){
    return syscall(SYS_futex,uaddr,futex_op,val,timeout,uaddr,val3);
}


void read_shared_mem(){

    int n;
    if ((shmid = shmget(20541, sizeof(file_entry) + 256, IPC_CREAT | 0666)) == -1) {
        printf("shmget");
        exit(2);
    }

    entries = (file_entry *) shmat(shmid, 0, 0);
    if (entries == NULL) {
        printf("problem2");
        exit(2);
    }
}

void write_0_shared_mem(){

    if ((shmid = shmget(20541, sizeof(file_entry) + 256, IPC_CREAT | 0666)) == -1) {
        printf("problem3");
        exit(2);
    }

    entries = (file_entry *) shmat(shmid, 0, 0);
    if (entries == NULL ) {
        printf("problem4");
        exit(2);
    }

    int pidD = 0;
    entries->pid  = pidD;
    shmdt(&shmid);
}


void write_1_shared_mem(){

    if ((shmid = shmget(20541, sizeof(file_entry) + 256, IPC_CREAT | 0666)) == -1) {
        printf("problem3");
        exit(2);
    }

    entries = (file_entry *) shmat(shmid, 0, 0);
    if (entries == NULL ) {
        printf("problem4");
        exit(2);
    }

    int pidD = 1;
    entries->pid  = pidD;
    shmdt(&shmid);
 }



 static void fwait(file_entry *futexp){
    int s;
    while (1) {
    if(futexp->pid==1) {
        write_0_shared_mem();
        break;
    }

    s = futex(&futexp->pid, FUTEX_WAIT, 0, NULL, NULL, 0);
    if (s == -1 && errno != EAGAIN)
        exit("futex-FUTEX_WAIT");
    }
}


static void fpost(file_entry *futexp){
    int s;

    if(futexp->pid==0){
        write_1_shared_mem();
        s = futex(&futexp->pid, FUTEX_WAKE, 1, NULL, NULL, 0);
        if (s  == -1)
            exit("futex-FUTEX_WAKE");
    }
}


int main(){
    int volatile I;
    read_shared_mem();
    fwait(entries);

    for(i=0;i<5;i++){
        printf("i=%d\n",I);
    }

    fpost(entries);

    return 0;

}

输出

$./progA

Thread 3 created
Thread 3 created
Thread 4 created
Thread 4 created
Thread 2 created
i=0
i=1
i=2
i=3
i=4
Thread 4 finished
i=0
i=1
i=2
i=3
i=4
i=0
i=1
i=2
i=3
i=4
Thread 4 finished
Thread 4 finished
i=0
i=1
i=2
i=3
i=4
i=0
i=1
i=2
i=3
i=4
Thread 4 finished
Thread 4 finished
4

0 回答 0