#include
#include
#include
#include
#include
#include
#include
// 为了通用性,我们不使用POSIX线程,而使用标准C库的简单模拟
// 但是题目要求用C语言实现多线程,所以我们需要使用pthread
// 在Windows下需要链接pthread库,这里假设Linux环境
#include
#ifdef __APPLE__
// macOS 下 pthread 可用
#endif
#define MAX_UNITS 1000
#define MAX_DAYS 30
// 车辆状态
typedef enum {
VEHICLE_IDLE, // 空闲
VEHICLE_LOADING, // 装货
VEHICLE_TRANSITING, // 在途
VEHICLE_UNLOADING, // 卸货
VEHICLE_MAINTENANCE // 维修
} VehicleState;
// 车辆结构
typedef struct {
int id; // 车辆编号
VehicleState state; // 当前状态
int remaining_time; // 剩余时间 (分钟)
int transits; // 完成运输次数
double total_distance; // 总行驶距离 (km)
int total_waiting_time; // 总等待时间 (分钟)
int break_remaining; // 本次连续工作剩余可行驶时间 (分钟)
int daily_drive; // 当天累计驾驶时间 (分钟)
char driver_name[32]; // 司机姓名
int is_running; // 线程运行标志
int speed; // 车速 km/h
int load_time; // 每趟装货时间 (分钟)
int unload_time; // 每趟卸货时间 (分钟)
double avg_speed_in_town; // 城内平均速度
double avg_speed_highway; // 高速平均速度
int max_continuous_drive; // 最长连续驾驶时间 (分钟)
int min_rest_time; // 最少休息时间 (分钟)
int max_daily_drive; // 日最大驾驶时间 (分钟)
int rest_time_left; // 当前休息还需多少分钟
int is_on_rest; // 是否在休息
pthread_mutex_t mutex;
} Vehicle;
// 任务结构
typedef struct {
int vehicle_id;
double distance;
int is_highway;
int load_time;
int unload_time;
} Task;
// 全局变量
Vehicle vehicles[MAX_UNITS];
int vehicle_count = 0;
pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER;
int simulation_day = 0; // 当前模拟天数 (0~29)
int simulation_minute = 0; // 当前模拟分钟 (0~1439)
int simulation_running = 1;
int total_completed = 0; // 总完成趟数
double total_distance = 0; // 总行驶距离
// 日志函数
void log_message(const char* msg) {
pthread_mutex_lock(&log_mutex);
printf("[Day %d, %02d:%02d] %s\n", simulation_day + 1,
simulation_minute / 60, simulation_minute % 60, msg);
pthread_mutex_unlock(&log_mutex);
}
// 生成随机数 [min, max]
int rand_int(int min, int max) {
return min + rand() % (max - min + 1);
}
// 初始化车辆
void init_vehicles(int count) {
vehicle_count = (count > MAX_UNITS) ? MAX_UNITS : count;
for (int i = 0; i < vehicle_count; i++) {
vehicles[i].id = i + 1;
vehicles[i].state = VEHICLE_IDLE;
vehicles[i].remaining_time = 0;
vehicles[i].transits = 0;
vehicles[i].total_distance = 0;
vehicles[i].total_waiting_time = 0;
vehicles[i].break_remaining = 240; // 默认连续驾驶4小时
vehicles[i].daily_drive = 0;
vehicles[i].is_running = 1;
vehicles[i].speed = rand_int(40, 80); // 速度
vehicles[i].load_time = rand_int(10, 30);
vehicles[i].unload_time = rand_int(10, 30);
vehicles[i].avg_speed_in_town = rand_int(20, 40);
vehicles[i].avg_speed_highway = rand_int(60, 100);
vehicles[i].max_continuous_drive = 240; // 4小时
vehicles[i].min_rest_time = 20;
vehicles[i].max_daily_drive = 480; // 8小时
vehicles[i].rest_time_left = 0;
vehicles[i].is_on_rest = 0;
snprintf(vehicles[i].driver_name, sizeof(vehicles[i].driver_name),
"司机%03d", i + 1);
pthread_mutex_init(&vehicles[i].mutex, NULL);
}
}
// 生成随机任务(返回是否生成了任务)
int generate_task(Task* task, int vehicle_id) {
// 随机决定是否生成任务(30%概率)
if (rand() % 100 < 30) {
task->vehicle_id = vehicle_id;
task->distance = rand_int(20, 500);
task->is_highway = rand() % 2;
task->load_time = vehicles[vehicle_id].load_time;
task->unload_time = vehicles[vehicle_id].unload_time;
return 1;
}
return 0;
}
// 车辆线程函数
void* vehicle_thread(void* arg) {
int id = *(int*)arg;
free(arg);
Vehicle* v = &vehicles[id];
while (simulation_running && v->is_running) {
// 模拟时间推进(每个循环代表1分钟)
pthread_mutex_lock(&v->mutex);
// 处理休息状态
if (v->is_on_rest) {
v->rest_time_left--;
if (v->rest_time_left <= 0) {
v->is_on_rest = 0;
v->break_remaining = v->max_continuous_drive;
v->state = VEHICLE_IDLE;
char buf[100];
snprintf(buf, sizeof(buf), "车辆%d司机%s完成休息,恢复空闲", v->id, v->driver_name);
log_message(buf);
}
pthread_mutex_unlock(&v->mutex);
continue; // 休息期间不处理其他
}
switch (v->state) {
case VEHICLE_IDLE: {
// 生成任务(此处简化:每1分钟检查一次是否分配任务)
Task task;
if (generate_task(&task, v->id)) {
// 有任务,开始装货
v->state = VEHICLE_LOADING;
v->remaining_time = task.load_time;
v->total_waiting_time += 0; // 等待时间计算在空闲中?
char buf[100];
snprintf(buf, sizeof(buf), "车辆%d开始装货,预计%d分钟", v->id, v->remaining_time);
log_message(buf);
} else {
// 无任务,空闲累计等待时间
v->total_waiting_time++;
}
break;
}
case VEHICLE_LOADING: {
v->remaining_time--;
if (v->remaining_time <= 0) {
// 装货完成,开始运输
v->state = VEHICLE_TRANSITING;
// 随机生成行程距离(实际应该由任务决定,但为了简化,直接随机)
double dist = rand_int(50, 300);
v->remaining_time = (int)((dist / v->speed) * 60);
v->total_distance += dist;
char buf[100];
snprintf(buf, sizeof(buf), "车辆%d装货完毕,开始运输,距离%.0fkm,预计%d分钟", v->id, dist, v->remaining_time);
log_message(buf);
}
break;
}
case VEHICLE_TRANSITING: {
// 检查是否需要强制休息(连续驾驶超过4小时)
if (v->break_remaining <= 0) {
// 必须休息
v->is_on_rest = 1;
v->rest_time_left = v->min_rest_time;
v->state = VEHICLE_IDLE; // 暂时空闲状态(但实际在休息)
v->is_on_rest = 1; // 重设
char buf[100];
snprintf(buf, sizeof(buf), "车辆%d连续驾驶超时,强制休息%d分钟", v->id, v->min_rest_time);
log_message(buf);
break;
}
// 计算本分钟行驶的距离(按速度)
double speed_now = v->speed; // 简化使用固定速度
v->total_distance += speed_now / 60.0; // 每分钟行驶 km
v->remaining_time--;
v->break_remaining--;
v->daily_drive++;
// 检查日驾驶时间限制
if (v->daily_drive >= v->max_daily_drive) {
// 达到日限,需要休息到第二天?此处简化:直接结束当天任务
v->state = VEHICLE_IDLE;
char buf[100];
snprintf(buf, sizeof(buf), "车辆%d今日驾驶时间已达上限,停止运输", v->id);
log_message(buf);
// 实际上应该让车辆停止到第二天,但仿真中我们让线程休眠到第二天?不好处理,先这样。
}
if (v->remaining_time <= 0) {
// 到达目的地,开始卸货
v->state = VEHICLE_UNLOADING;
v->remaining_time = v->unload_time;
char buf[100];
snprintf(buf, sizeof(buf), "车辆%d到达目的地,开始卸货,预计%d分钟", v->id, v->unload_time);
log_message(buf);
}
break;
}
case VEHICLE_UNLOADING: {
v->remaining_time--;
if (v->remaining_time <= 0) {
// 卸货完成,增加运输次数
v->transits++;
total_completed++;
v->state = VEHICLE_IDLE;
char buf[100];
snprintf(buf, sizeof(buf), "车辆%d卸货完成,总运输次数%d", v->id, v->transits);
log_message(buf);
}
break;
}
case VEHICLE_MAINTENANCE: {
// 维修中,剩余时间递减
v->remaining_time--;
if (v->remaining_time <= 0) {
v->state = VEHICLE_IDLE;
char buf[100];
snprintf(buf, sizeof(buf), "车辆%d维修完毕,恢复空闲", v->id);
log_message(buf);
}
break;
}
default:
break;
}
pthread_mutex_unlock(&v->mutex);
// 睡眠1ms模拟1分钟(实际时间加速比,可根据需要调整)
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = 1000000; // 1ms
nanosleep(&ts, NULL);
}
return NULL;
}
// 时间推进线程(模拟一天中的分钟)
void* time_thread(void* arg) {
while (simulation_running) {
// 每循环代表现实1ms,模拟1分钟
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = 1000000; // 1ms
nanosleep(&ts, NULL);
pthread_mutex_lock(&log_mutex);
simulation_minute++;
if (simulation_minute >= 1440) {
simulation_minute = 0;
simulation_day++;
// 重置日驾驶时间
for (int i = 0; i < vehicle_count; i++) {
pthread_mutex_lock(&vehicles[i].mutex);
vehicles[i].daily_drive = 0;
pthread_mutex_unlock(&vehicles[i].mutex);
}
if (simulation_day >= MAX_DAYS) {
simulation_running = 0;
}
}
pthread_mutex_unlock(&log_mutex);
}
return NULL;
}
// 维修事件(随机让车辆进入维修)
void* maintenance_thread(void* arg) {
while (simulation_running) {
// 每10秒(对应10000分钟?实际是10ms)检查一次
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = 10000000; // 10ms
nanosleep(&ts, NULL);
if (rand() % 1000 < 5) { // 0.5%概率触发维修
int idx = rand() % vehicle_count;
pthread_mutex_lock(&vehicles[idx].mutex);
if (vehicles[idx].state == VEHICLE_IDLE || vehicles[idx].state == VEHICLE_TRANSITING) {
// 模拟途中故障或闲置时维修
vehicles[idx].state = VEHICLE_MAINTENANCE;
vehicles[idx].remaining_time = rand_int(30, 120);
char buf[100];
snprintf(buf, sizeof(buf), "车辆%d发生故障,进入维修,预计%d分钟", vehicles[idx].id, vehicles[idx].remaining_time);
log_message(buf);
}
pthread_mutex_unlock(&vehicles[idx].mutex);
}
}
return NULL;
}
int main(int argc, char* argv[]) {
srand(time(NULL));
int vehicle_num = 10; // 默认10辆车
if (argc > 1) {
vehicle_num = atoi(argv[1]);
if (vehicle_num <= 0 || vehicle_num > MAX_UNITS) vehicle_num = 10;
}
init_vehicles(vehicle_num);
printf("=== 物流运输多线程模拟开始 ===\n");
printf("车辆数量: %d\n", vehicle_count);
printf("模拟天数: %d\n", MAX_DAYS);
pthread_t time_tid, maint_tid;
pthread_create(&time_tid, NULL, time_thread, NULL);
pthread_create(&maint_tid, NULL, maintenance_thread, NULL);
pthread_t v_tids[MAX_UNITS];
for (int i = 0; i < vehicle_count; i++) {
int* id = malloc(sizeof(int));
*id = i;
pthread_create(&v_tids[i], NULL, vehicle_thread, id);
}
// 等待所有线程结束
for (int i = 0; i < vehicle_count; i++) {
pthread_join(v_tids[i], NULL);
}
simulation_running = 0;
pthread_join(time_tid, NULL);
pthread_join(maint_tid, NULL);
// 输出统计
printf("\n=== 模拟结束 ===\n");
printf("总完成运输趟数: %d\n", total_completed);
for (int i = 0; i < vehicle_count; i++) {
Vehicle* v = &vehicles[i];
printf("车辆%d (司机%s): 趟数=%d, 总距离=%.1fkm, 总等待=%d分钟\n",
v->id, v->driver_name, v->transits, v->total_distance, v->total_waiting_time);
}
// 清理
for (int i = 0; i < vehicle_count; i++) {
pthread_mutex_destroy(&vehicles[i].mutex);
}
pthread_mutex_destroy(&log_mutex);
return 0;
}