简体   繁体   English

C-Linux-Pthread和信号量

[英]C - Linux - Pthreads and Semaphore

I am having trouble trying to implement semaphores with pthreads. 我在尝试使用pthreads实现信号量时遇到了麻烦。 The scenario that I am trying to program are rats in a maze. 我要编程的场景是迷宫中的老鼠。 Where rats are threads and the maze consists of rooms connected to each other. 老鼠是线,而迷宫则由相互连接的房间组成。 The rats have to traverse through each room with each room having a different capacity and wait time before a rat can move on. 老鼠必须穿过每个房间,每个房间的容量和等待时间都不同,老鼠才能继续前进。 I was able to implement it with a while loop and let the threads sit and spin while waiting for a spot to free up but I need to achieve the objective with semaphores. 我能够使用while循环来实现它,并让线程坐着旋转,同时等待释放一个点,但是我需要使用信号量来实现目标。 Here's what I have: 这是我所拥有的:

sem_t psem, csem;

void EnterRoom(int iRat, int iRoom) {

    time_t currentTime;

    currentTime = time(NULL);

    RoomVB[iRoom][iRat].tEntry = currentTime - startTime;
    RoomVB[iRoom][iRat].iRat = iRat;
    VisitorCount[iRoom]++;
    sleep(roomArray[iRoom].delay);
}

void LeaveRoom(int iRat, int iRoom) {

    time_t currentTime;

    currentTime = time(NULL);

    VisitorCount[iRoom]--;
    RoomVB[iRoom][iRat].tDep = currentTime - startTime;
}

void *rat(void *ratID) {

    if (sem_init(&csem, 0, 0) < 0) {
        perror("sem_init");
        exit(1);
    }

    int id;

    id = (int)ratID;

    int i;

    for (i = 0; i < numOfRooms; i++) {

    /*while (VisitorCount[i] >= roomArray[i].capacity) {

    }*/

    if (sem_init(&psem, 0, roomArray[i].capacity) < 0) {
        perror("sem_init");
        exit(1);
        }


    sem_wait(&psem);
    EnterRoom(id, i);
    sem_post(&csem);

    sem_wait(&csem);
    LeaveRoom(id, i);
    sem_post(&psem);

    }

    return NULL;

}

As you can see I commented out the while loop. 如您所见,我注释了while循环。 I had to incorporate additional information like the time it it takes for a rat to travel through rooms in a 2D array. 我必须合并其他信息,例如老鼠在2D阵列中穿过房间所花费的时间。

Error result: 错误结果:

Rat 0 completed maze in 5 seconds.
Rat 1 completed maze in 5 seconds.
Rat 2 completed maze in 5 seconds.
Room 0 [3 1]: 0 0 1; 1 0 1; 2 0 1; 
Room 1 [2 2]: 0 1 3; 1 1 3; 2 1 3; 
Room 2 [1 2]: 0 3 5; 1 3 5; 2 3 5; 
Total traversal time: 15 seconds, compared to ideal time: 15 seconds.

Correct result (achieved with loop): 正确的结果(通过循环实现):

Rat 0 completed maze in 7 seconds.
Rat 1 completed maze in 5 seconds.
Rat 2 completed maze in 9 seconds.
Room 0 [3 1]: 0 0 1; 1 0 1; 2 0 1; 
Room 1 [2 2]: 0 1 3; 1 1 3; 2 3 5; 
Room 2 [1 2]: 0 5 7; 1 3 5; 2 7 9; 
Total traversal time: 21 seconds, compared to ideal time: 15 seconds.

I assume I need two semaphores with the producer semaphore being initially set to n - which is the capacity of each room. 我假设我需要两个信号量,而生产者信号量最初设置为n-这是每个房间的容量。 Any ideas how I fix it so it works as it should? 有什么想法我如何解决它才能正常工作吗?

You can't have each thread re-initialise the same two shared semaphores simultaneously. 您不能让每个线程同时重新初始化相同的两个共享信号量。 The semaphores all need to be initialised up-front, before your rats start running. 在您的老鼠开始奔跑之前,所有信号量都需要预先初始化。

The easiest way to solve this will be to have one semaphore for each room, initialised to the capacity of that room (store the sempahore in the roomArray element for that room). 解决此问题的最简单方法是为每个房间设置一个信号灯,并初始化为该房间的容量(将信号灯存储在该房间的roomArray元素中)。 Then, just have the rat wait on the semaphore when it enters the room, and post the semaphore when it exits the room. 然后,让老鼠在进入房间时等待信号量,然后在离开房间时张贴信号量。

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

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