eventfd 和线程的关键部分

critical sections with eventfd and threads

我有一点问题似乎无法解决。我正在尝试实施一个程序(对于 uni class),它将有 n 列火车和 m 列火车。但是,由于我的车站数量可能少于试图访问它们的火车,我想在关键部分(这将是我的火车站)添加一个类似信号量的机制,但我们必须使用而不是使用信号量我们 os class 中的 eventfd。 现在我的代码(到目前为止)的问题似乎是 none 我的火车线程实际上进入了一个车站。

我的代码是:

    //Task 1 - sync via eventfd 
//train example : 6 trains and just 3 alleys in a critical section -> train station
// threads = trains will stay = sleep in trainstation and print their current state

#include <sys/eventfd.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <stdint.h> //needed for our in-kernel counter
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/shm.h>

//eventfd: read with EFD_SEMAPHORE will decrease counter by 1 and return 1
// int eventfd(unsigned int initval, int flags);
// without just the previous value and resets to zero
// if eventfd counter is at zero when trying to read, it will block until it turns nonzero again (only if fd is not nonblocking!)
// ssize_t read(int fd, void *buf, size_t count); returns no of bytes if it succeeds
// write adds a number to our 64 bit in-kernel counter
// ssize_t write(int fd, const void *buf, size_t count);
// fd is readable to select, poll, epoll if the counter is non zero
// select - monitors multiple fds until one or more turn "ready"
// poll - waits for an event on a fd 
// epoll - similar to poll - monitors multiple fds to see if i/o is possible (great for large numbers of fds)
// close - required to release the fd - if all fds get closed = resources will be freed by the kernel
// return value = fd used to refer to the eventfd object; unsuccessful = -1

#define fail(msg) {printf(msg); return EXIT_FAILURE;}

struct stationStruct{
    int stations[3];
    uint64_t sem[3];
};

void threadfunction(void* station){
    int n = 3;
    struct stationStruct *st = station;
    int stillWaiting = 1;
    //reads eventfd to check wether train can enter or not
    while(stillWaiting != 0){
        for(int i = 0; i < n && stillWaiting != 0; i++){
            if(read(st->stations[i], (void*) st->sem[i], sizeof(uint64_t)) > 0){
                stillWaiting = 0;
                printf("\n\ntrain no %ld has arrived at train station no %d \n", (long) pthread_self(), i);
                sleep(1);
                printf("train no %ld is ready for departure\n", (long) pthread_self());
                sleep(2);
                printf("train no %ld has left the train station %d\n", (long) pthread_self(), i);
                //writes in order to release the locked eventfd
                write(st->stations[i], (void*) st->sem[i], sizeof(uint64_t));
                break;
                }
                //else{
                //sleep(3);
                //printf("train %ld has failed to enter station %d\n", (long) pthread_self(), i);
            //}
        }
    }
    pthread_exit((void*)pthread_self);
}

int main(int argc, char const *argv[])
{
    int n = 3;
    int m = 4;
    struct stationStruct station;

    //eventfd creation
    for(int i = 0; i < n; i ++){
        if((station.stations[i] = eventfd(1, EFD_SEMAPHORE)) > 0){
            printf("Station %d is open\n", i);
        }
        else{
            fail("could not initialize eventfd for station A\n");
        }
    }

    pthread_t threads[m];
    int returnedValues[m];

    printf("Train Stations 0 - %d are open \n", n);
    for(int i = 0; i < m; i++){
        sleep(1);
        if(pthread_create(&threads[i], NULL, (void*) &threadfunction, (void*)&station) != 0){
            fail("trains did not arrive\n");
        }
    }

    for(int i = 0; i < m; i++){
        pthread_join(threads[i], (void*) &returnedValues[i]);
        printf("Traind %ld left for good\n", (long) threads[i]);
    }

    printf("Train stations are closing now...\n");
    for(int i = 0; i < n; i++){
        printf("sation %d has been closed\n", i);
        close(station.stations[i]);
    }

    printf("Main station has been closed\n");

    return EXIT_SUCCESS;
}

#define _XOPEN_SOURCE

非常感谢您的宝贵时间和帮助!

好像是指针的小错误?

if(read(st->stations[i], (void*) st->sem[i], sizeof(uint64_t)) > 0){

...

write(st->stations[i], (void*) st->sem[i], sizeof(uint64_t));

应该是

if(read(st->stations[i], &st->sem[i], sizeof(uint64_t)) > 0){

...

write(st->stations[i], &st->sem[i], sizeof(uint64_t));