繁体   English   中英

eventfd和线程的关键部分

[英]critical sections with eventfd and threads

我有一个问题,似乎无法解决。 我正在尝试实现一个程序(对于uni类),该程序将具有n列火车和m列火车。 但是,由于我的车站数量可能少于尝试访问它们的火车,因此我想在关键路段(将是我的火车站)添加类似信号灯的机制,但是我们不必使用信号灯,我们的os类中的eventfd。 现在(到目前为止)我的代码存在的问题似乎是我的所有火车线程实际上都没有进入车站。

我的代码是:

    //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));

暂无
暂无

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

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