1

我需要使用信号量在 C89 中实现生产者和消费者。

我承认这是为了学校作业,所以我将主要使用伪代码。

我花了很长时间来简化我的代码,所以希望有人能找出问题所在

有一个全局变量:

threadQueue ready; //global queue that holds all the threads ready to be run

这些是我在代码中使用的函数。我试图让它们不言自明:

NewThread(Function); //turns a function into a thread
RotateQueue(Queue); //rotates the Queue so the head becomes the tail and next becomes the head
Add2Queue(Thread, Queue); //adds a thread to a queue
RunThread(NewThread); //stops the current thread, and runs NewThread
RemoveHead(Queue); //removes the head of the queue and returns it

以下是我设计信号量的方式:

struct semaphore{
    threadQueue queue;
    int val;
}

wait(semaphore s)
{
    if(--s.val < 0)
    {
        Add2Queue(currentThread, s.queue);
        RunThread(ready.head);
    }
}

signal(semaphore s)
{
    if(s.val++ < 0)
    {
        Add2Queue(removeHead(s.queue), ready);
    }
    RotateQueue(ready);
    RunThread(ready.head);
}

最后,这是我运行代码的地方:

semaphore mutex = 1;
semaphore taken = 0;
semaphore remaining = some number;

producer()
{
    while(1)
    {
        wait(remaining);
        wait(mutex);
        //critical section
        signal(mutex);
        signal(taken);
    }
}

consumer()
{
    while(1)
    {
        wait(taken);
        wait(mutex);
        //critical section
        signal(mutex);
        signal(remaining);
    }
}

main()
{
    thread produce = NewThread(producer);
    thread consume = NewThread(consumer);

    Add2Queue(produce, ready);
    Add2Queue(consume, ready);

    RunThread(ready.head);      
}

我的代码目前这样做:

  1. 开始生产线程
  2. 在信号(互斥)之后切换到消耗线程
  3. 启动消费线程
  4. 切换到第二个消费线程?在等待(采取)
  5. 启动第二个线程
  6. 切换到第三个消费线程??在等待(采取)
  7. Add2Queue 上的 SegFaults

我很确定 signal() 和 wait() 不正确并导致我所有的问题,但我不知道我需要改变什么。

请帮忙!

4

0 回答 0