五一假期作业

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.mzph.cn/bicheng/79786.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Liunx安装Apache Tomcat

目录 一、了解tomcat 二、下载 三、启动tomcat 四、网页访问tomcat 五、Tomcat修改默认8080端口 六、Tomcat创建项目步骤-实现项目对外访问 一、了解tomcat Apache Tomcat 是一个开源的 Java Servlet 容器 和 Web 服务器&#xff0c;主要用于运行基于 Java 的 Web 应用…

破局者手册 Ⅰ:测试开发核心基础,解锁未来测试密钥!

目录 一、引入背景 二、软件测试基础概念 2.1 软件测试的定义 2.2 软件测试的重要性 2.3 软件测试的原则 三、测试类型 3.1 功能测试 3.2 接口测试 3.2.1 接口测试的概念 3.2.2 接口测试的重要性 3.2.3 接口测试的要点 3.2.4 接口测试代码示例&#xff08;Python r…

C++ 适配器模式详解

适配器模式&#xff08;Adapter Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许不兼容的接口之间能够协同工作。 概念解析 适配器模式的核心思想是&#xff1a; 接口转换&#xff1a;将一个类的接口转换成客户希望的另一个接口 兼容性&#xff1a;使原本由于接…

【NLP】 28. 语言模型的评估方式:MRR, PERPLEXITY, BLEU, WER从困惑度到实际效果

语言模型的评估方式&#xff1a;从困惑度到实际效果 评估语言模型&#xff08;LLM&#xff09;是否有效&#xff0c;并不仅仅是看它生成句子是否“听起来通顺”&#xff0c;我们需要定量的指标对模型性能做出系统性评价。评估方法主要分为两大类&#xff1a; 内在评价&#x…

Java 企业级开发设计模式全解析

Java 企业级开发设计模式全解析 在 Java 企业级开发的复杂领域中&#xff0c;设计模式如同精湛的工匠工具&#xff0c;能够帮助开发者构建高效、可维护、灵活且健壮的软件系统。它们是无数开发者在长期实践中总结出的解决常见问题的最佳方案&#xff0c;掌握这些模式对于提升开…

小刚说C语言刷题—1038编程求解数学中的分段函数

1.题目描述 编程求解数学中的分段函数。 …………x1 (当 x>0 )。 yf(x)…0 (当 x0 )。 ………x−1 (当 x<0 )。 上面描述的意思是&#xff1a; 当x>0 时 yx1 ; 当 x0 时 y0 ; 当 x<0 时 yx−1 。 输入 输入一行&#xff0c;只有一个整数x(−30000≤x≤30…

滚珠螺杆的精度如何保持?

滚珠螺杆通常用于需要精确定位的地方&#xff0c;高机械效率、低传递扭矩和几乎为零的轴向游隙&#xff0c;使滚珠螺杆成为工具定位和飞机副翼驱动等应用中的重要设备。但是&#xff0c;连续工作产生的阻力和热量会导致较大的摩擦力和定位误差。那么&#xff0c;滚珠螺杆的精度…

在 Laravel 中深度集成 Casbin 到原生 Auth 系统

在 Laravel 中深度集成 Casbin 到原生 Auth 系统需要实现多层次的融合&#xff0c;以下是专业级实现方案&#xff1a; 一、核心集成架构 #mermaid-svg-WYM1aoAyHrR5bCdp {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-…

JavaScript 实现输入框的撤销功能

在 Web 开发中&#xff0c;为输入框添加撤销功能可以极大地提升用户体验&#xff0c;方便用户快速回滚到之前的输入状态。本文将通过一段简单的 HTML、CSS 和 JavaScript 代码&#xff0c;详细介绍如何实现输入框的撤销功能。 整体实现思路 利用 JavaScript 监听输入框的inpu…

计算机视觉与深度学习 | 点云配准算法综述(1992-2025)

点云配准算法综述(1992-2025) 点云配准 点云配准算法综述(1992-2025)一、传统方法(1992-2020)1. **ICP(Iterative Closest Point)**2. **NDT(Normal Distributions Transform)**3. **4PCS(4-Points Congruent Sets)**二、深度学习驱动的方法(2018-2025)1. **Poin…

数据库的二级索引

二级索引 10.1 二级索引作为额外的键 表结构 正如第8章提到的&#xff0c;二级索引本质上是包含主键的额外键值对。每个索引通过B树中的键前缀来区分。 type TableDef struct {// 用户定义的部分Name stringTypes []uint32 // 列类型Cols []string // 列名Indexes …

Java IO流核心处理方式详解

一、IO流概述 Java IO&#xff08;Input/Output&#xff09;流是处理输入输出操作的核心机制&#xff0c;通过流&#xff08;Stream&#xff09;的形式实现设备间的数据传输。所有操作都基于以下两个核心抽象&#xff1a; InputStream/OutputStream&#xff1a;字节流基类 Re…

WidowX-250s 机械臂的简单数字孪生案例

前面一段时间记录了一下WidowX-250s机械臂的学习与遥操作演示&#xff0c;相关链接如下&#xff1a; WidowX-250s 机械臂学习记录&#xff1a; https://blog.csdn.net/qq_54900679/article/details/145556979 WidowX-250s 机械臂遥操作演示记录&#xff1a; https://blog.c…

uniapp 云开发全集 云开发的概念

一、云开发的概念 1.1 云开发介绍 云开发 unicloud 是 DCloud 联合阿里云、腾讯云、支付宝云&#xff0c;为开发者提供的基于 serverless 模式和 js 编程的云开发平台&#xff0c;可以使用极小的成本代价开发具轻松实现前后台整体业务。 1.2 云开发的核心组成 云开发的核心组…

GGD独立站的优势

GGD模式(基于Google生态的独立站模式)越来越受欢迎&#xff0c;主要有以下原因&#xff1a; 1. 全球化覆盖 GGD独立站依托Google强大的生态系统&#xff0c;能够帮助企业轻松触达全球用户&#xff0c;实现国际化布局&#xff0c;拓展业务范围。Google作为全球最大的搜索引擎&…

签名去背景图像处理实例

一、前言 在生活中我们经常用到电子签名&#xff0c;但有时候我们所获取的图像的彩色图像&#xff0c;我们需要获取白底黑字的电子签名&#xff0c;我们可以通过下面程序对彩色图像进行处理达到我们的处理目的。 原始彩色图像如下&#xff1a; 二、程序和运行结果 clear all;c…

WebAssembly(Wasm):现代Web开发的超级加速器

在当今的Web开发领域&#xff0c;性能和效率是开发者们永恒的追求目标。随着Web应用的复杂度不断增加&#xff0c;传统的JavaScript在某些场景下已经难以满足高性能计算和复杂逻辑处理的需求。此时&#xff0c;WebAssembly&#xff08;Wasm&#xff09;作为一种新兴的Web技术&a…

简单理解MCP:AI如何使用工具

简单理解MCP&#xff1a;AI如何使用工具&#xff08;以天气/新闻服务为例&#xff09; 你是否注意到人工智能(AI)助手正变得越来越智能&#xff1f;它们不再仅仅是聊天&#xff0c;还能执行实际操作&#xff0c;比如查询天气、在线搜索&#xff0c;甚至预订会议。这通常涉及到…

护网奇谈: 红队工程师手记

零、引言&#xff1a;在演练中活着&#xff0c;在现实中消失 人们常说&#xff0c;护网是网络安全界的“大阅兵”。 每年一次&#xff0c;红蓝对阵&#xff0c;政企联动&#xff0c;战鼓擂响&#xff0c;态势大屏高挂&#xff0c;PPT如潮&#xff0c;报告成山。 你在屏幕前看…

机器翻译与数据集

机器翻译与数据集 语言模型是自然语言处理的关键&#xff0c;而机器翻译是语言模型最成功的基准测试。因为机器翻译正是将输入序列转换成输出序列的序列转换模型&#xff08;sequence transduction&#xff09;的核心问题。序列转换模型在各类现代人工智能应用中发挥着至关重要…