- 实验内容
1.编写一个简单的进程调度器,要求:
- (1)实现基于优先级的抢占式调度算法。
- (2)程序中需要包含进程创建、进程调度、进程结束等功能函数。
- (3)能够实现多个进程的并发执行,能够正确处理进程的状态转换
2.编写一个生产者-消费者模型,其中生产者和消费者共享一个缓冲区。生产者不断产生物品并把它们放入缓冲区,消费者不断从缓冲区中取出物品。当缓冲区为空时,消费者等待生产者;当缓冲区已满时,生产者等待消费者。要求:
(1)缓冲区大小为10;
(2)合理地使用信号量,保证生产者和消费者之间的正确交互,解决资源竞争和数据不一致的问题。当一个进程需要等待另一个进程完成某个操作时,使用信号量来实现进程同步;
- 代码实现(要求对代码作相应的注释)
- 进程调度器
#include <stdio.h>
#include <stdlib.h>
#define MAX_PROCESSES 10
typedef struct {
int pid; // 进程ID
int priority; // 优先级
int burst_time; // 执行时间
int remaining_time; // 剩余执行时间
int status; // 进程状态:0表示就绪,1表示运行,2表示结束
} Process;
Process processes[MAX_PROCESSES];
int num_processes = 0;
// 创建进程
void createProcess(int priority, int burst_time) {
if (num_processes >= MAX_PROCESSES) {
printf("无法创建更多进程。\n");
return;
}
Process new_process;
new_process.pid = num_processes + 1;
new_process.priority = priority;
new_process.burst_time = burst_time;
new_process.remaining_time = burst_time;
new_process.status = 0;
processes[num_processes] = new_process;
num_processes++;
}
// 进程调度
void schedule() {
int i, highest_priority = -1, highest_priority_index = -1;
// 找到优先级最高的就绪进程
for (i = 0; i < num_processes; i++) {
if (processes[i].status == 0 && processes[i].priority > highest_priority) {
highest_priority = processes[i].priority;
highest_priority_index = i;
}
}
// 更新进程状态
for (i = 0; i < num_processes; i++) {
if (i == highest_priority_index) {
processes[i].status = 1; // 设置为运行状态
} else if (processes[i].status == 1) {
processes[i].status = 0; // 设置为就绪状态
}
}
}
// 进程结束
void endProcess(int pid) {
int i;
// 找到对应进程并设置为结束状态
for (i = 0; i < num_processes; i++) {
if (processes[i].pid == pid) {
processes[i].status = 2;
break;
}
}
}
// 打印进程信息
void printProcesses() {
int i;
printf("进程信息:\n");
printf("PID\t优先级\t执行时间\t剩余时间\t状态\n");
for (i = 0; i < num_processes; i++) {
printf("%d\t%d\t%d\t\t%d\t\t", processes[i].pid, processes[i].priority, processes[i].burst_time, processes[i].remaining_time);
if (processes[i].status == 0) {
printf("就绪\n");
} else if (processes[i].status == 1) {
printf("运行\n");
} else if (processes[i].status == 2) {
printf("结束\n");
}
}
}
int main() {
createProcess(2, 5);
createProcess(1, 3);
createProcess(3, 2);
printProcesses();
schedule();
printProcesses();
endProcess(2);
printProcesses();
return 0;
}
- 生产者-消费者模型
//一直生产消费的生产者-消费者模型
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#define BUFFER_SIZE 10
#define NUM_PRODUCERS 2
#define NUM_CONSUMERS 2
int buffer[BUFFER_SIZE];
int in = 0;
int out = 0;
HANDLE empty; // 空槽位的信号量
HANDLE full; // 已占用槽位的信号量
HANDLE mutex; // 互斥信号量,用于保护缓冲区的访问
DWORD WINAPI producer(LPVOID arg) {
int item;
while (1) {
item = rand() % 100; // 产生一个随机物品
WaitForSingleObject(empty, INFINITE); // 等待空槽位
WaitForSingleObject(mutex, INFINITE); // 互斥访问缓冲区
buffer[in] = item; // 将物品放入缓冲区
in = (in + 1) % BUFFER_SIZE;
ReleaseMutex(mutex);
ReleaseSemaphore(full, 1, NULL); // 增加已占用槽位的信号量
printf("生产者 %d 生产了物品 %d\n", *((int *)arg), item);
Sleep(rand() % 3000); // 随机休眠一段时间
}
return 0;
}
DWORD WINAPI consumer(LPVOID arg) {
int item;
while (1) {
WaitForSingleObject(full, INFINITE); // 等待已占用槽位
WaitForSingleObject(mutex, INFINITE); // 互斥访问缓冲区
item = buffer[out]; // 从缓冲区取出物品
out = (out + 1) % BUFFER_SIZE;
ReleaseMutex(mutex);
ReleaseSemaphore(empty, 1, NULL); // 增加空槽位的信号量
printf("消费者 %d 消费了物品 %d\n", *((int *)arg), item);
Sleep(rand() % 3000); // 随机休眠一段时间
}
return 0;
}
int main() {
int i;
HANDLE producers[NUM_PRODUCERS];
HANDLE consumers[NUM_CONSUMERS];
int producer_ids[NUM_PRODUCERS];
int consumer_ids[NUM_CONSUMERS];
// 初始化信号量
empty = CreateSemaphore(NULL, BUFFER_SIZE, BUFFER_SIZE, NULL);
full = CreateSemaphore(NULL, 0, BUFFER_SIZE, NULL);
mutex = CreateMutex(NULL, FALSE, NULL);
// 创建生产者线程
for (i = 0; i < NUM_PRODUCERS; i++) {
producer_ids[i] = i + 1;
producers[i] = CreateThread(NULL, 0, producer, (LPVOID)&producer_ids[i], 0, NULL);
}
// 创建消费者线程
for (i = 0; i < NUM_CONSUMERS; i++) {
consumer_ids[i] = i + 1;
consumers[i] = CreateThread(NULL, 0, consumer, (LPVOID)&consumer_ids[i], 0, NULL);
}
// 等待生产者线程结束
WaitForMultipleObjects(NUM_PRODUCERS, producers, TRUE, INFINITE);
// 等待消费者线程结束
WaitForMultipleObjects(NUM_CONSUMERS, consumers, TRUE, INFINITE);
// 关闭句柄
CloseHandle(empty);
CloseHandle(full);
CloseHandle(mutex);
return 0;
}
//加了停止条件的生产者-消费者模型
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define BUFFER_SIZE 10
#define NUM_PRODUCERS 2
#define NUM_CONSUMERS 2
int buffer[BUFFER_SIZE];
int in = 0;
int out = 0;
int stop = 0;
HANDLE mutex;
HANDLE empty;
HANDLE full;
DWORD WINAPI producer(LPVOID arg) {
int item;
while (!stop) {
item = rand() % 100; // 产生一个随机物品
WaitForSingleObject(empty, INFINITE);
WaitForSingleObject(mutex, INFINITE);
buffer[in] = item; // 将物品放入缓冲区
in = (in + 1) % BUFFER_SIZE;
ReleaseMutex(mutex);
ReleaseSemaphore(full, 1, NULL);
printf("生产者 %d 生产了物品 %d\n", *((int*)arg), item);
Sleep((rand() % 3) * 1000); // 随机休眠一段时间
}
return 0;
}
DWORD WINAPI consumer(LPVOID arg) {
int item;
while (!stop) {
WaitForSingleObject(full, INFINITE);
WaitForSingleObject(mutex, INFINITE);
item = buffer[out]; // 从缓冲区取出物品
out = (out + 1) % BUFFER_SIZE;
ReleaseMutex(mutex);
ReleaseSemaphore(empty, 1, NULL);
printf("消费者 %d 消费了物品 %d\n", *((int*)arg), item);
Sleep((rand() % 3) * 1000); // 随机休眠一段时间
}
return 0;
}
int main() {
HANDLE producers[NUM_PRODUCERS];
HANDLE consumers[NUM_CONSUMERS];
int producer_ids[NUM_PRODUCERS];
int consumer_ids[NUM_CONSUMERS];
mutex = CreateMutex(NULL, FALSE, NULL);
empty = CreateSemaphore(NULL, BUFFER_SIZE, BUFFER_SIZE, NULL);
full = CreateSemaphore(NULL, 0, BUFFER_SIZE, NULL);
// 创建生产者线程
for (int i = 0; i < NUM_PRODUCERS; i++) {
producer_ids[i] = i + 1;
producers[i] = CreateThread(NULL, 0, producer, &producer_ids[i], 0, NULL);
}
// 创建消费者线程
for ( i = 0; i < NUM_CONSUMERS; i++) {
consumer_ids[i] = i + 1;
consumers[i] = CreateThread(NULL, 0, consumer, &consumer_ids[i], 0, NULL);
}
// 运行一段时间后停止生产者和消费者
Sleep(10 * 1000);
stop = 1;
// 等待生产者线程结束
WaitForMultipleObjects(NUM_PRODUCERS, producers, TRUE, INFINITE);
// 等待消费者线程结束
WaitForMultipleObjects(NUM_CONSUMERS, consumers, TRUE, INFINITE);
CloseHandle(mutex);
CloseHandle(empty);
CloseHandle(full);
return 0;
}