gpt4 book ai didi

eventfd 和线程的关键部分

转载 作者:太空宇宙 更新时间:2023-11-04 02:35:51 25 4
gpt4 key购买 nike

我有一点问题似乎无法解决。我正在尝试实现一个程序(针对 uni 类),该程序将有 n 列火车和 m 列火车。但是,由于我的车站数量可能少于试图访问它们的火车,我想在关键部分(这将是我的火车站)添加一个类似信号量的机制,但我们必须使用而不是使用信号量我们操作系统类中的 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));

关于eventfd 和线程的关键部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37674476/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com