1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
| #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <windows.h> #include <process.h> #include <stdlib.h> #include <conio.h> #include <string.h> #include <time.h>
#define BUFFER_SIZE 20 #define PRODUCER_COUNT 3 #define CONSUMER_COUNT 3 #define MAX_SLEEP_TIME 3000
typedef struct { int buffer[BUFFER_SIZE]; int in; int out; int count; } Buffer;
Buffer shared_buffer = { {0}, 0, 0, 0 }; HANDLE empty_semaphore; HANDLE full_semaphore; CRITICAL_SECTION mutex; volatile LONG running = TRUE; FILE* log_file;
void set_thread_random_seed(int thread_id) { unsigned int seed = (unsigned int)(time(NULL) + thread_id); srand(seed); }
void log_operation(int id, int item, char type) { EnterCriticalSection(&mutex); const char* operation = (type == 'P') ? "生产者" : "消费者"; printf("%s %d %s了数据: %d\n", operation, id, (type == 'P') ? "生产" : "消费", item); fprintf(log_file, "%s %d %s了数据: %d\n", operation, id, (type == 'P') ? "生产" : "消费", item);
printf("缓冲区状态: "); fprintf(log_file, "缓冲区状态: "); for (int i = 0; i < BUFFER_SIZE; i++) { printf("%2d ", shared_buffer.buffer[i]); fprintf(log_file, "%2d ", shared_buffer.buffer[i]); }
printf("\n入口指针: %d, 出口指针: %d, 当前使用量: %d/%d\n", shared_buffer.in, shared_buffer.out, shared_buffer.count, BUFFER_SIZE); fprintf(log_file, "\n入口指针: %d, 出口指针: %d, 当前使用量: %d/%d\n", shared_buffer.in, shared_buffer.out, shared_buffer.count, BUFFER_SIZE); printf("----------------------------------------\n"); fprintf(log_file, "----------------------------------------\n"); LeaveCriticalSection(&mutex); }
unsigned __stdcall producer(void* arg) { int id = *(int*)arg; set_thread_random_seed(id);
while (InterlockedCompareExchange(&running, TRUE, TRUE)) { int item = rand() % 20 + 1;
WaitForSingleObject(empty_semaphore, INFINITE); EnterCriticalSection(&mutex);
shared_buffer.buffer[shared_buffer.in] = item; shared_buffer.in = (shared_buffer.in + 1) % BUFFER_SIZE; shared_buffer.count++;
log_operation(id, item, 'P');
LeaveCriticalSection(&mutex); ReleaseSemaphore(full_semaphore, 1, NULL);
Sleep(rand() % (MAX_SLEEP_TIME + 1)); } return 0; }
unsigned __stdcall consumer(void* arg) { int id = *(int*)arg; set_thread_random_seed(id);
while (InterlockedCompareExchange(&running, TRUE, TRUE)) { WaitForSingleObject(full_semaphore, INFINITE); EnterCriticalSection(&mutex);
int item = shared_buffer.buffer[shared_buffer.out]; shared_buffer.buffer[shared_buffer.out] = 0; shared_buffer.out = (shared_buffer.out + 1) % BUFFER_SIZE; shared_buffer.count--;
log_operation(id, item, 'C');
LeaveCriticalSection(&mutex); ReleaseSemaphore(empty_semaphore, 1, NULL);
Sleep(rand() % (MAX_SLEEP_TIME + 1)); } return 0; }
void create_threads(HANDLE* threads, int* ids, unsigned(__stdcall* func)(void*), int count) { for (int i = 0; i < count; i++) { ids[i] = i + 1; threads[i] = (HANDLE)_beginthreadex(NULL, 0, func, &ids[i], 0, NULL); } }
void wait_for_exit() { while (InterlockedCompareExchange(&running, TRUE, TRUE)) { if (_kbhit() && _getch() == 27) { printf("检测到 ESC 键,准备退出程序...\n"); InterlockedExchange(&running, FALSE); break; } Sleep(10); }
ReleaseSemaphore(full_semaphore, CONSUMER_COUNT, NULL); ReleaseSemaphore(empty_semaphore, PRODUCER_COUNT, NULL); }
int main() { log_file = fopen("data.txt", "w"); if (log_file == NULL) { printf("无法创建日志文件。\n"); return -1; }
empty_semaphore = CreateSemaphore(NULL, BUFFER_SIZE, BUFFER_SIZE, NULL); full_semaphore = CreateSemaphore(NULL, 0, BUFFER_SIZE, NULL); InitializeCriticalSection(&mutex);
memset(shared_buffer.buffer, 0, sizeof(shared_buffer.buffer));
HANDLE producers[PRODUCER_COUNT]; HANDLE consumers[CONSUMER_COUNT]; int producer_ids[PRODUCER_COUNT]; int consumer_ids[CONSUMER_COUNT];
printf("按 ESC 键退出程序...\n"); create_threads(producers, producer_ids, producer, PRODUCER_COUNT); create_threads(consumers, consumer_ids, consumer, CONSUMER_COUNT);
wait_for_exit();
WaitForMultipleObjects(PRODUCER_COUNT, producers, TRUE, INFINITE); WaitForMultipleObjects(CONSUMER_COUNT, consumers, TRUE, INFINITE);
DeleteCriticalSection(&mutex); CloseHandle(empty_semaphore); CloseHandle(full_semaphore);
for (int i = 0; i < PRODUCER_COUNT; i++) CloseHandle(producers[i]); for (int i = 0; i < CONSUMER_COUNT; i++) CloseHandle(consumers[i]);
fclose(log_file); printf("程序已退出。\n"); return 0; }
|