c语言(1)由用户指定要产生的进程及其类别,存入就绪队列。 (2)调度程序从就绪队列中提取一个就绪进程运行,如果申请的资源不存在则进入相应的等待队列,调度程序调度就绪队列中的下一个进程;进程运行结束时,会检查相应的等侍队列,激活等待队列中的进程进人就绪队列;运行结束的进程进入over链表。重复这一过程直至就绪队列为空。 (3)程序询问是否要继续?如果要继续转至(1)开始执行,否则退出程序。
时间: 2024-02-29 12:52:49 浏览: 81
以下是一个简单的生产者消费者问题模型的C语言实现,其中包括进程控制块的定义、就绪队列、等待队列、缓冲区等关键数据结构的定义,以及进程创建、等待、唤醒、销毁等关键函数的实现。
```
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define BUFFER_SIZE 10
typedef struct {
int pid;
char type;
int system_id;
char product;
char state;
struct pcb *next;
} pcb;
typedef struct {
pcb *head;
pcb *tail;
} queue;
int pid = 0;
queue ready_queue;
queue producer_queue;
queue consumer_queue;
queue over_queue;
char buffer[BUFFER_SIZE];
int in = 0, out = 0;
HANDLE sem_empty, sem_full, mutex;
pcb *new_pcb(char type) {
pcb *p = (pcb *) malloc(sizeof(pcb));
p->pid = ++pid;
p->type = type;
p->system_id = 0;
p->product = '\0';
p->state = 'w';
p->next = NULL;
return p;
}
void enqueue(queue *q, pcb *p) {
if (q->head == NULL) {
q->head = p;
q->tail = p;
} else {
q->tail->next = p;
q->tail = p;
}
}
pcb *dequeue(queue *q) {
pcb *p = q->head;
if (p != NULL) {
q->head = p->next;
if (q->head == NULL) {
q->tail = NULL;
}
}
return p;
}
void print_queue(queue *q) {
pcb *p = q->head;
while (p != NULL) {
printf("pid=%d, type=%c, system_id=%d, product=%c, state=%c\n", p->pid, p->type, p->system_id, p->product, p->state);
p = p->next;
}
}
void print_buffer() {
int i;
for (i = 0; i < BUFFER_SIZE; i++) {
printf("%c ", buffer[i]);
}
printf("\n");
}
void produce_product(pcb *p) {
WaitForSingleObject(sem_empty, INFINITE);
WaitForSingleObject(mutex, INFINITE);
int i = 0;
while (buffer[in] != '\0') {
p->state = 'w';
enqueue(&producer_queue, p);
printf("Producer %d waiting for buffer to be empty\n", p->pid);
print_queue(&producer_queue);
ReleaseMutex(mutex);
WaitForSingleObject(sem_empty, INFINITE);
WaitForSingleObject(mutex, INFINITE);
}
buffer[in] = p->product;
in = (in + 1) % BUFFER_SIZE;
printf("Producer %d produced product %c\n", p->pid, p->product);
print_buffer();
pcb *p1 = dequeue(&consumer_queue);
if (p1 != NULL) {
p1->state = 'r';
p1->product = buffer[out];
out = (out + 1) % BUFFER_SIZE;
printf("Consumer %d consumed product %c\n", p1->pid, p1->product);
print_buffer();
p1->system_id = GetCurrentThreadId();
enqueue(&ready_queue, p1);
}
ReleaseMutex(mutex);
ReleaseSemaphore(sem_full, 1, NULL);
}
void consume_product(pcb *p) {
WaitForSingleObject(sem_full, INFINITE);
WaitForSingleObject(mutex, INFINITE);
int i = 0;
while (buffer[out] == '\0') {
p->state = 'w';
enqueue(&consumer_queue, p);
printf("Consumer %d waiting for buffer to be full\n", p->pid);
print_queue(&consumer_queue);
ReleaseMutex(mutex);
WaitForSingleObject(sem_full, INFINITE);
WaitForSingleObject(mutex, INFINITE);
}
p->product = buffer[out];
out = (out + 1) % BUFFER_SIZE;
printf("Consumer %d consumed product %c\n", p->pid, p->product);
print_buffer();
pcb *p1 = dequeue(&producer_queue);
if (p1 != NULL) {
p1->state = 'r';
buffer[in] = p1->product;
in = (in + 1) % BUFFER_SIZE;
printf("Producer %d produced product %c\n", p1->pid, p1->product);
print_buffer();
p1->system_id = GetCurrentThreadId();
enqueue(&ready_queue, p1);
}
ReleaseMutex(mutex);
ReleaseSemaphore(sem_empty, 1, NULL);
}
void run_process(pcb *p) {
if (p->type == 'P') {
produce_product(p);
} else if (p->type == 'C') {
consume_product(p);
}
p->state = 'o';
p->system_id = GetCurrentThreadId();
enqueue(&over_queue, p);
}
DWORD WINAPI thread_func(LPVOID lpParam) {
pcb *p = (pcb *) lpParam;
p->state = 'r';
p->system_id = GetCurrentThreadId();
run_process(p);
ExitThread(0);
}
int main() {
int n, i;
printf("Enter the number of processes: ");
scanf("%d", &n);
printf("Enter the type of each process (P for producer, C for consumer):\n");
for (i = 0; i < n; i++) {
char type;
printf("Process %d: ", i + 1);
scanf(" %c", &type);
pcb *p = new_pcb(type);
enqueue(&ready_queue, p);
}
sem_empty = CreateSemaphore(NULL, BUFFER_SIZE, BUFFER_SIZE, NULL);
sem_full = CreateSemaphore(NULL, 0, BUFFER_SIZE, NULL);
mutex = CreateMutex(NULL, FALSE, NULL);
while (ready_queue.head != NULL) {
pcb *p = dequeue(&ready_queue);
HANDLE hThread = CreateThread(NULL, 0, thread_func, p, 0, NULL);
CloseHandle(hThread);
}
printf("All processes have finished.\n");
printf("Over queue:\n");
print_queue(&over_queue);
CloseHandle(sem_empty);
CloseHandle(sem_full);
CloseHandle(mutex);
return 0;
}
```
在该程序中,使用链队列维护了四个关键队列:就绪队列、生产者等待队列、消费者等待队列、已结束队列。使用信号量和互斥锁实现了生产者消费者问题的同步和互斥。在进程运行结束时,将其加入已结束队列并打印。
请注意,该程序仅供参考,可能存在不足之处,需要根据实际情况进行修改和调整。
阅读全文