C 中信号量的线程同步

问题描述 投票:0回答:1

我正在做一项作业,要求我模拟一辆巴士从 A 站到 B 站一次又一次地行驶,而学生可以上下车。

我对公交车和学生的整个例行程序进行了编码,但我似乎无法让它们正确同步。

作为什么有效、什么无效的示例,以下是具有 4 个学生/线程(加上总线线程)的程序单个周期的示例运行:

sample run of one cycle

如您所见,巴士在 A 站初始化,学生已创建并正确上车(学生 3 无法上车,因为系规定:同一系的 N / 4 名学生)可以在给定时间在公共汽车上,此处 N = 4)。 当公交车到达B站时,车上所有学生都应下车前往大学。这里,只有学生 1 下车。

这是学生和公交车的行程:

void* student_routine(void* argv){

    // decrement semaphore by 1
    sem_wait(&semaphore);

    struct student* student = search_node(student_list, (int)argv);

    // if bus is not at stop A or student can't get in then wait
    pthread_mutex_lock(&mutex);
    while(bus->bus_position != Stop_A || !check_department(student)){
        pthread_cond_wait(&cond_A, &mutex);
    }
    pthread_mutex_unlock(&mutex);

    // decrease bus capacity for this department by 1 and get student in the bus
    bus->department_capacity[student->department]--;
    stop_A[student->AM - 1] = -1;
    bus_array[student->AM - 1] = student->AM;
    printf(ANSI_GREEN "Student %d is boarding the bus from Stop A" ANSI_RESET "\n", student->AM);
    print_areas();

    // if bus is not at stop B then wait
    pthread_mutex_lock(&mutex);
    while(bus->bus_position != Stop_B){
        pthread_cond_wait(&cond_B, &mutex);
    }
    pthread_mutex_unlock(&mutex);

    // get off bus, go to university and study
    bus->department_capacity[student->department]++;
    bus_array[student->AM - 1] = -1;
    university[student->AM - 1] = student->AM;
    printf(ANSI_GREEN "Student %d is going to the University to study" ANSI_RESET "\n", student->AM);
    print_areas();

    sleep(student->study_time); // simulate studying
    printf(ANSI_GREEN "Student %d finished studying after %d seconds" ANSI_RESET "\n", student->AM, student->study_time);

    // after studying, go to stop B
    university[student->AM - 1] = -1;
    stop_B[student->AM - 1] = student->AM;
    printf(ANSI_GREEN "Student %d is going from University to Stop B" ANSI_RESET "\n", student->AM);
    print_areas();

    // if bus is not at stop B or student can't get in then wait
    pthread_mutex_lock(&mutex);
    while(bus->bus_position != Stop_B || !check_department(student)){
        pthread_cond_wait(&cond_B, &mutex);
    }
    pthread_mutex_unlock(&mutex);

    // decrease bus capacity for this department by 1 and get student in the bus
    bus->department_capacity[student->department]--;
    stop_B[student->AM - 1] = -1;
    bus_array[student->AM - 1] = student->AM;
    printf(ANSI_GREEN "Student %d is boarding the bus from Stop B" ANSI_RESET "\n", student->AM);
    print_areas();

    // if bus is not at stop A then wait
    pthread_mutex_lock(&mutex);
    while(bus->bus_position != Stop_A){
        pthread_cond_wait(&cond_A, &mutex);
    }
    pthread_mutex_unlock(&mutex);

    // go home
    bus_array[student->AM - 1] = -1;
    printf(ANSI_GREEN "Student %d is going home" ANSI_RESET "\n", student->AM);
    delete_node(student_list, student->AM);
    print_areas();

    sem_post(&semaphore);
    
    return NULL;

}

void* bus_routine(){

    while(true){

        printf(ANSI_BLUE "Bus arrived at Stop A" ANSI_RESET "\n" );
        print_areas();

        bus->bus_position = Stop_A;     // go to Stop_A
        pthread_cond_signal(&cond_A);   // signal that the bus arrived at Stop A
        sleep(BUS_WAIT_TIME);           // wait 3 sec for students to get in

        printf(ANSI_BLUE "Bus travelling to Stop B" ANSI_RESET "\n");
        print_areas();

        bus->bus_position = In_Transit; // bus is in transit
        sleep(BUS_TRANSITION_TIME);     // simulate the bus travelling to Stop_B

        printf(ANSI_BLUE "Bus arrived at Stop B" ANSI_RESET "\n");
        print_areas();

        bus->bus_position = Stop_B;     // go to Stop_B
        pthread_cond_signal(&cond_B);   // signal that the bus arrived at Stop B
        sleep(BUS_WAIT_TIME);           // wait 3 sec for students to get in

        printf(ANSI_BLUE "Bus travelling to Stop A" ANSI_RESET "\n");
        print_areas();
        
        bus->bus_position = In_Transit; // bus is in transit
        sleep(BUS_TRANSITION_TIME);     // simulate the bus travelling to Stop_A

    }

}

我了解到信号量无法正常工作。我能做什么来修复它? 任何答案将不胜感激。

c multithreading pthreads
1个回答
0
投票

使用信号量和互斥锁+条件变量是没有意义的。

Cond var 方法

演员

学生

  1. 锁定互斥体。
  2. 等待巴士到达出发地。
  3. 乘车:
    1. 调整计数。
    2. 信号条件变量
  4. 等待巴士到达目的地。
  5. 下车巴士:
    1. 调整计数。
    2. 信号条件变量
  6. 解锁互斥体。

需要数据

  • 起源。
  • 目的地。
  • (无需存储指示他们是否在公交车上的标志。)

巴士

  1. 锁定互斥锁。
  2. 虽然还没有完成,
    1. 对于行程中的每一站,
      1. 调整位置。
      2. 广播条件变种。
      3. 等到所有要下车的乘客都下车了。
      4. 广播条件变种。
      5. 等到巴士满员或没有人想上车。
  3. 解锁互斥体。

需要数据

  • 座位数。
  • 乘客人数。
  • (无需存储当前位置。)

注释

广播显着简化了这里的代码。

© www.soinside.com 2019 - 2024. All rights reserved.