0

我编写了一个模拟生产者消费者问题的程序,我遇到了几个问题。这是使用 Win32 API 编写的。

我正在使用两个满和空的信号量来对存储项目的缓冲区执行计数。还有一个互斥锁来控制对临界区的访问。我有两个功能:一个基于简单的计算创建一个项目:线程 * 1000000 + 计数,而另一个消耗它。

缓冲区中有 10 个空格,但是程序应该希望能够为不同数量的空格和线程工作。生产者线程通过缓冲区然后重新开始,直到信号量达到 10。我遇到了两个问题,我似乎也找不到解决方案,也没有在调试器中获得很多细节。

1)具有 printf() 函数的注释部分每次都会使线程崩溃。没有任何东西被打印到控制台。我也尝试过只使用一个字符串,而没有输出其他变量。没有成功。我发现 printf() 在多线程环境中使用时可能会遇到问题的文档,但是在这种情况下,它位于关键部分内,并且在第一次尝试时会崩溃。如何将该信息打印到控制台?

2)当我删除打印语句并运行代码时,线程每次仍然在不同的点崩溃。我不知道为什么。生产者线程应该等待空信号量和互斥体,将项目放入,然后增加完整信号量的计数(表示已添加项目)。当它达到 10 时,它应该停止。消费者线程等待完整的信号量和互斥量,删除一个项目,然后增加空信号量的计数。我写的方式有什么导致这些线程退出的吗?

这就是我得到的:

程序“[5348] OperatingSystem.exe”已退出,代码为 0 (0x0)。

#include<stdio.h>
#include<windows.h>
#include<ctype.h>
#include<tchar.h>
#include<strsafe.h>
#include<conio.h>
#include<time.h>


#define threads 1
#define MAX 10


typedef struct objects {
HANDLE empty;
HANDLE full;
HANDLE mutex;
int buffer[10];
};


  struct objects data;


DWORD WINAPI Producers(LPVOID lpParam){
int count = 0;
int item;
while (TRUE){
    if (data.buffer[count] == 0){
        WaitForSingleObject(data.empty, INFINITE);
        WaitForSingleObject(data.mutex, INFINITE);
        item = threads * 1000000 + count;
        data.buffer[count] = item;
        //printf("Producer has produced: %d", item);
        ReleaseMutex(data.mutex);
        ReleaseSemaphore(data.full, 1, NULL);
    }
    count++;
    if (count == 10){ count = 0; }
};
}


DWORD WINAPI Consumers(LPVOID lpParam){
int count = 0;
while (TRUE){
    if (data.buffer[count] != 0){
        WaitForSingleObject(data.full, INFINITE);
        WaitForSingleObject(data.mutex, INFINITE);
        //printf("Consumer has consummed: %d", data.buffer[count]);
        data.buffer[count] = 0;
        ReleaseMutex(data.mutex);
        ReleaseSemaphore(data.empty, 1, NULL);
    }
    count++;
    if (count == 10){ count = 0; }
};



}

int main(int argc, char *argv[]) {

struct objects data;
LONG initialCount = 0;
LONG maxCount = 10;
data.empty = CreateSemaphore(NULL, maxCount, maxCount, NULL);
data.full = CreateSemaphore(NULL, initialCount, maxCount, NULL);
data.mutex = CreateMutex(NULL, FALSE, NULL);


DWORD ConsumerId[threads];
HANDLE ConsumerThread[threads];
DWORD ProducerId[threads];
HANDLE ProducerThread[threads];


for (int i = 0; i < threads; i++){
    ProducerThread[i] = CreateThread(
        NULL,
        0,
        Producers,
        NULL,
        0,
        &ProducerId[i]);


    ConsumerThread[i] = CreateThread(
        NULL,
        0,
        Consumers,
        NULL,
        0,
        &ConsumerId[i]);
}
}
4

0 回答 0