当前位置: 首页 > news >正文

五一假期作业

sub_process.c

#include <stdio.h>         // 标准输入输出库
#include <pthread.h>       // POSIX线程库
#include <sys/ipc.h>       // IPC基础定义(如消息队列/共享内存)
#include <sys/msg.h>       // 消息队列操作相关
#include <sys/shm.h>        // 共享内存操作相关
#include <unistd.h>         // 标准符号常量和类型
#include <string.h>         // 字符串操作相关#define NUM_THREADS 4      // 定义线程数量为4
#define MAX_MSG_SIZE 1024  // 定义单条消息的最大长度// 消息队列数据结构
struct msg_buffer 
{long msg_type;          // 消息类型标识(必须非0)char msg_text[MAX_MSG_SIZE]; // 实际消息内容缓冲区
};// 共享内存数据结构
struct shm_data
{int char_count[256];    // ASCII字符频率统计数组(支持扩展ASCII)pthread_mutex_t lock;   // 互斥锁保护共享数据
};int shmid; // 全局共享内存ID,供子进程或线程使用// 线程处理函数:负责从消息队列读取日志并统计字符
void* process_log(void* arg) 
{int msgid = *(int*)arg; // 从参数获取消息队列ID(潜在问题:传递局部变量地址)struct msg_buffer msg;  // 定义接收消息的临时缓冲区// 阻塞式接收消息队列中类型为1的消息ssize_t bytes_received = msgrcv(msgid, &msg, MAX_MSG_SIZE, 1, 0);if (bytes_received == -1){perror("msgrcv"); // 如果接收失败则打印错误信息return NULL;}// 将共享内存附加到当前进程的地址空间struct shm_data* shm = shmat(shmid, NULL, 0);if (shm == (void*)-1) {perror("shmat"); // 如果附加失败则打印错误信息return NULL;}// 遍历接收到的消息内容进行字符统计for (int i = 0; i < bytes_received; i++) {   unsigned char c = msg.msg_text[i]; // 取当前字符(无符号避免负数索引)pthread_mutex_lock(&shm->lock);     // 加锁保护共享数据shm->char_count[c]++;              // 对应字符计数+1pthread_mutex_unlock(&shm->lock);  // 解锁}shmdt(shm); // 分离共享内存(不影响其他进程/线程的挂接)return NULL;
}int main() {// 生成IPC对象唯一键值(基于文件路径和项目ID)key_t key = ftok("/tmp/logfile", 65);if (key == -1){perror("ftok"); // 如果生成失败则退出程序return 1;}// 创建消息队列(权限0666,若不存在则创建)int msgid = msgget(key, 0666 | IPC_CREAT);if (msgid == -1) {perror("msgget"); // 如果获取失败则退出程序return 1;}// 创建共享内存段(大小为shm_data结构体,权限0666,若不存在则创建)shmid = shmget(key, sizeof(struct shm_data), 0666 | IPC_CREAT);if (shmid == -1){perror("shmget"); // 如果创建失败则退出程序return 1;}// 将共享内存附加到当前进程地址空间并进行初始化struct shm_data* shm = shmat(shmid, NULL, 0);memset(shm, 0, sizeof(struct shm_data)); // 清空共享内存内容pthread_mutex_init(&shm->lock, NULL);    // 初始化互斥锁// 创建线程池(NUM_THREADS个线程)pthread_t threads[NUM_THREADS];for (int i = 0; i < NUM_THREADS; i++) {// 创建线程并传递消息队列ID指针(潜在问题:msgid是栈变量)if (pthread_create(&threads[i], NULL, process_log, &msgid) != 0){perror("pthread_create"); // 如果线程创建失败则退出程序return 1;}}// 等待所有线程执行完毕for (int i = 0; i < NUM_THREADS; i++) {pthread_join(threads[i], NULL);}// 分离共享内存(主进程不再需要访问)shmdt(shm);return 0;
}

main_process.c

#include <stdio.h>         // 标准输入输出库
#include <sys/ipc.h>       // IPC基础定义(消息队列/共享内存等)
#include <sys/shm.h>        // 共享内存操作相关函数
#include <pthread.h>       // POSIX线程库
#include <unistd.h>         // 标准符号常量和类型// 共享内存结构体(与子进程保持一致)
struct shm_data 
{int char_count[256];    // ASCII字符频率统计数组(支持扩展ASCII)pthread_mutex_t lock;   // 互斥锁保护共享数据
};int main() 
{// 生成唯一键值(基于文件路径和项目ID)key_t key = ftok("/tmp/logfile", 65);if (key == -1){perror("ftok"); // 如果生成键值失败则退出程序return 1;}// 创建或获取共享内存段(大小为shm_data结构体)int shmid = shmget(key, sizeof(struct shm_data), 0666 | IPC_CREAT);if (shmid == -1) {perror("shmget"); // 如果获取共享内存失败则退出程序return 1;}// 将共享内存映射到当前进程地址空间struct shm_data* shm = shmat(shmid, NULL, 0);if (shm == (void*)-1) {perror("shmat"); // 如果映射失败则退出程序return 1;}// 实时监控循环(永久运行直到程序被强制终止)while (1) {sleep(1); // 每隔1秒更新一次统计信息// 加锁以保护共享数据pthread_mutex_lock(&shm->lock);printf("===== 字符统计 =====
");// 遍历所有可能的ASCII字符for (int i = 0; i < 256; i++) {if (shm->char_count[i] > 0) // 仅显示出现过的字符{if (i == ' ') {printf("空格: %d
", shm->char_count[i]); // 特殊处理空格字符} else {printf("%c: %d
", (char)i, shm->char_count[i]); // 显示可打印字符}}}// 解锁以允许其他线程访问pthread_mutex_unlock(&shm->lock);}// 分离共享内存(实际上不会执行到这里)shmdt(shm);return 0;
}

monitor.c

#include <stdio.h>         // 标准输入输出库
#include <sys/ipc.h>       // IPC基础定义(消息队列/共享内存等)
#include <sys/shm.h>        // 共享内存操作相关函数
#include <pthread.h>       // POSIX线程库
#include <unistd.h>         // 标准符号常量和类型// 共享内存结构体(与子进程保持一致)
struct shm_data 
{int char_count[256];    // ASCII字符频率统计数组(支持扩展ASCII)pthread_mutex_t lock;   // 互斥锁保护共享数据
};int main() 
{// 生成唯一键值(基于文件路径和项目ID)key_t key = ftok("/tmp/logfile", 65);if (key == -1){perror("ftok"); // 如果生成键值失败则退出程序return 1;}// 创建或获取共享内存段(大小为shm_data结构体)int shmid = shmget(key, sizeof(struct shm_data), 0666 | IPC_CREAT);if (shmid == -1) {perror("shmget"); // 如果获取共享内存失败则退出程序return 1;}// 将共享内存映射到当前进程地址空间struct shm_data* shm = shmat(shmid, NULL, 0);if (shm == (void*)-1) {perror("shmat"); // 如果映射失败则退出程序return 1;}// 实时监控循环(永久运行直到程序被强制终止)while (1) {sleep(1); // 每隔1秒更新一次统计信息// 加锁以保护共享数据pthread_mutex_lock(&shm->lock);printf("===== 字符统计 =====
");// 遍历所有可能的ASCII字符for (int i = 0; i < 256; i++) {if (shm->char_count[i] > 0) // 仅显示出现过的字符{if (i == ' ') {printf("空格: %d
", shm->char_count[i]); // 特殊处理空格字符} else {printf("%c: %d
", (char)i, shm->char_count[i]); // 显示可打印字符}}}// 解锁以允许其他线程访问pthread_mutex_unlock(&shm->lock);}// 分离共享内存(实际上不会执行到这里)shmdt(shm);return 0;
}
编译和运行
# 创建共享内存键值文件
touch /tmp/logfile# 编译代码
gcc main_process.c -o main_process
gcc sub_process.c -o sub_process -lpthread
gcc monitor.c -o monitor -lpthread# 生成测试日志
base64 /dev/urandom | head -n 1000 > test.log# 按顺序启动进程
./sub_process &
./monitor &
./main_process

手动终止进程

  1. 查找进程ID
    在终端中执行以下命令,找到相关进程的PID:

    ps aux | grep -E 'main_process|sub_process|monitor'
    
  2. 终止进程
    使用 kill 命令逐个终止进程:

     

牛客网刷题

http://www.dtcms.com/a/172732.html

相关文章:

  • android-ndk开发(4): linux开发机有线连接android设备
  • Go小技巧易错点100例(二十九)
  • 关于毕业论文,查重,AIGC
  • 【漫话机器学习系列】240.真正类率(True Positive Rate,TPR)
  • C++演讲比赛案例代码
  • AI日报 · 2025年5月05日|雅诗兰黛与微软合作成立 AI 创新实验室,加速美妆产品研发与营销
  • LCD,LED
  • AI笔记-1
  • 稀疏性预测算法初步
  • 文心一言开发指南13——文心一言API两种调用方式的区别
  • cpp学习笔记1--class
  • 【QT】QT安装
  • Python生活手册-NumPy数组创建:从快递分拣到智能家居的数据容器
  • Springboot循环依赖
  • React-router v7 第八章(边界处理)
  • AI向量检索
  • DeepSeek提示词的技巧
  • URL混淆与权限绕过技术
  • Linux | WEB服务器的部署及优化
  • Doo全自动手机壳定制系统
  • 安全为上,在系统威胁建模中使用量化分析
  • 5G网络的安全挑战与应对策略:技术剖析与Python实战
  • 博图V20编译报错:备不受支持,无法编译。请更改为受支持的设备。
  • 解读《国家数据标准体系建设指南》:数据治理视角
  • [machine learning] Transformer - Attention (四)
  • Deepseek核心技术:模态穿透技术的实现原理与过程
  • 刷leetcodehot100返航版--哈希表5/5
  • OpenGl实战笔记(1)基于qt5.15.2+mingw64+opengl绘制三角形
  • Gradio全解20——Streaming:流式传输的多媒体应用(6)——构建视频流目标检测系统
  • Qt 信号槽机制底层原理学习