C 线程中的睡眠理发师问题

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

我正在尝试使用C语言和线程来解决睡觉的理发师问题。我写了一个主函数,还有线程控制的理发师和顾客函数。

由于某种原因,我的程序无法正常退出并在某处卡住或死锁。我的怀疑在于等待顾客的计数,因为从日志中可以看出,有些顾客来了,但没有得到服务。

我在这里附上我的代码。原型中列出的函数仅打印日志(*_service 除外,它等待 SERVICE_TIME)

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <stdbool.h>
#include <time.h>

#define CUSTOMERS 5
#define CHAIRS 1
#define SERVICE_TIME 100
#define MIN_INTERVAL 30
#define MAX_INTERVAL 80

// Values for the barber and customers synchronization
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t barber_available = PTHREAD_COND_INITIALIZER;
pthread_cond_t customer_waiting = PTHREAD_COND_INITIALIZER;

int waiting = 0; // Number of customers waiting
bool is_barber_sleeping = true;

// Prototype of functions
void *barber(void *arg);
void *customer(void *arg);
void barber_sleep();
void barber_service();
void customer_entry(int number);
void customer_wait(int number);
void customer_service(int number);
void customer_exit(int number);
void customer_reject(int number);

int served_customers = 0;
int rejected_customers = 0;

int main()
{
    pthread_t barber_thread, customer_threads[CUSTOMERS];
    srand((unsigned)time(NULL));

    // Create barber thread
    pthread_create(&barber_thread, NULL, barber, NULL);

    // Simulate the arrival of customers
    for (int i = 0; i < CUSTOMERS; i++)
    {
        pthread_create(&customer_threads[i], NULL, customer, (void *)(long)i);
        int interval = (rand() % (MAX_INTERVAL - MIN_INTERVAL + 1) + MIN_INTERVAL);
        usleep(interval * 1000); // Arrival of the next customer
    }

    // Wait for the end of the customer threads
    for (int i = 0; i < CUSTOMERS; i++)
    {
        pthread_join(customer_threads[i], NULL);
    }

    // End of the barber thread
    pthread_cancel(barber_thread);
    pthread_join(barber_thread, NULL);

    printf("Obsloužených zákazníků: %d\n", served_customers);
    printf("Odmítnutých zákazníků: %d\n", rejected_customers);

    return 0;
}

void *barber(void *arg)
{
    while (true)
    {
        // If there are no customers, the barber sleeps
        pthread_mutex_lock(&mutex);
        while (waiting == 0)
        {
            barber_sleep();
            is_barber_sleeping = true;
            // The barber waits for the customer to wake him up
            pthread_cond_wait(&customer_waiting, &mutex);
        }
        is_barber_sleeping = false;
        waiting--;
        pthread_mutex_unlock(&mutex);
        // The barber serves the customer (wait for SERVICE_TIME)
        barber_service();

        pthread_cond_signal(&barber_available);
    }
}

void *customer(void *arg)
{
    int number = (int)(long)arg;
    pthread_mutex_lock(&mutex);

    customer_entry(number);
    // If there is a free chair, the customer sits down
    if (waiting < CHAIRS)
    {
        waiting++;
        // If the barber is sleeping, the customer wakes him up
        if (is_barber_sleeping)
        {
            pthread_cond_signal(&customer_waiting);
        }
        else
        {
            customer_wait(number);
        }
        pthread_mutex_unlock(&mutex);

        pthread_mutex_lock(&mutex);
        // Customer waits for the barber to be available
        while (!is_barber_sleeping)
        {
            pthread_cond_wait(&barber_available, &mutex);
        }
        pthread_mutex_unlock(&mutex);
        // Customer is served
        customer_service(number);
        served_customers++;
    }
    else
    {
        // If there are no free chairs, the customer leaves
        pthread_mutex_unlock(&mutex);
        customer_reject(number);
        rejected_customers++;
    }

    customer_exit(number);
    return NULL;
}

我尝试更改锁定功能。我期望根据问题定义得到正确的输出。 该技术来自我的学校项目: 只能使用pthread_mutex_t和pthread_cond_t进行同步,否则项目将无法评估。

c multithreading synchronization semaphore
1个回答
0
投票

理发师和顾客都先打电话

pthread_mutex_lock(&mutex);
才可以做任何事情。

如果我们假设理发师线程自创建以来首先被调度(这可能但不能保证),那么理发师将永远等待顾客发出信号

customer_waiting
但没有顾客可以到达这一点,因为
mutex
已经被理发师锁住了。

这里可能还有其他错误,但马上肯定会陷入僵局。

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