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

Linux系统调用编程

目录

一. 理解进程和线程的概念。并在Linux系统下进行相应操作

1.1概念

1.1.1进程(Process)

1.1.2 线程(Thread)

1.2操作

1.2.1用 ps -a 命令查看系统中各进程的编号pid 

1.2.2用kill 命令终止一个进程pid

二. 解释Linux的“虚拟内存管理”,它与stm32中的 真实物理内存(内存映射)有什么区别?

2.1核心区别

2.2地址空间

2.3内存分配

2.4典型特征

2.5适用场景

三. 理解 Linux系统调用函数 fork()、wait()、exec() 等的含义和调用方法 。

3.1用putty或xterminal等工具软件进行操作。

3.1.1打开xterminal,连接服务器

3.1.2在home目录下创建工作目录

3.1.3使用vi创建C程序文件

3.1.4按i进入编辑模式,输入以下代码:

3.1.5使用gcc编译和运行程序

3.2在各小组的树莓派中,也手动创建组员的账号,组员在各自的账号+home目录下,完成同样的Linux系统调用函数练习。

3.2.1登录树莓派,打开端口进行账号密码的创建

3.2.2登录对应账号后进行编辑程序然后运行


一. 理解进程和线程的概念。并在Linux系统下进行相应操作

1.1概念

1.1.1进程(Process)

      定义

            进程是操作系统进行资源分配和调度的基本单位

            是程序的一次执行过程,具有独立的内存空间

      核心特征

            独立性:每个进程有独立的地址空间

            动态性:进程有创建、执行、暂停、终止等生命周期

            并发性:多个进程可以并发执行

            资源分配单位:CPU、内存等资源以进程为单位分配

       进程组成

            代码段(text)

            数据段(data)

            堆(heap)

            栈(stack)

            进程控制块(PCB)

       Linux中的进程

ps -aux  # 查看系统所有进程
top      # 动态查看进程状态

1.1.2 线程(Thread)

       定义

            线程是进程内的执行单元,是CPU调度的基本单位

           一个进程可以包含多个线程,共享进程的资源

      核心特征

           轻量级:创建/销毁开销比进程小

           共享性:同一进程的线程共享内存和资源

           独立性:有独立的执行路径和栈空间

           并发性:多线程可并发执行

      线程组成

           线程ID

           程序计数器

           寄存器集合

           栈空间

      Linux中的线程

ps -T -p <PID>  # 查看特定进程的线程
top -H          # 显示线程信息

1.2操作

1.2.1用 ps -a 命令查看系统中各进程的编号pid 

1.2.2用kill 命令终止一个进程pid

因为终止一个进程需要权限所以如果之输入

kill 240932

并不会成功

这里就需要输入来获得权限,就可以了

sudo kill 2409326

然后再用ps -a 命令查看系统中各进程的编号pid可以发现,已经成功终止

二. 解释Linux的“虚拟内存管理”,它与stm32中的 真实物理内存(内存映射)有什么区别?

2.1核心区别

      Linux使用虚拟内存(通过MMU实现地址转换),STM32使用物理内存直接映射(无MMU)
      Linux有内存保护机制(用户/内核态隔离),STM32所有代码均可访问全部内存

2.2地址空间

     Linux:每个进程有独立的4GB(32位)虚拟地址空间
     STM32:所有程序共享固定的物理地址空间(如Flash 0x08000000,SRAM 0x20000000)

2.3内存分配

     Linux:动态分配(malloc→brk/sbrk/mmap)
     STM32:静态分配(链接脚本确定,需手动管理)

2.4典型特征

     Linux支持:
         内存超额使用(Swap)
         写时复制(COW)
         内存共享(共享库)
    STM32特征
        确定性访问(无地址转换延迟)
        直接硬件操作(寄存器映射)
        无内存碎片风险(静态分配)

2.5适用场景

     选择Linux虚拟内存:需要多进程隔离、运行大型程序、内存需求超过物理内存时
     选择STM32物理映射:实时控制系统、资源受限(<1MB内存)场景、需要直接操作寄存器时

三. 理解 Linux系统调用函数 fork()、wait()、exec() 等的含义和调用方法 。

3.1用putty或xterminal等工具软件进行操作。

      远程登录自己被分配的阿里云服务器Ubuntu系统的账号(见下面附件),在自己的home目录下,创建一个作业子目录,然后学习使用vi 编辑一个c代码,gcc编译,实现一个系统调用函数的例子

3.1.1打开xterminal,连接服务器

3.1.2在home目录下创建工作目录

cd ~//判断是否在home目录
mkdir week6//创建一个名为week6的子目录
cd week6//进入子目录week6

3.1.3使用vi创建C程序文件

vi process.c//创建一个名为process.c的c文件并进入

3.1.4按i进入编辑模式,输入以下代码:

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>

int main() {
    printf("=== 系统调用演示程序 ===\n");
    printf("主进程PID: %d\n", getpid());

    // 1. fork()示例
    pid_t pid = fork();
    
    if (pid < 0) {
        perror("fork失败");
        return 1;
    }

    if (pid == 0) {
        // 子进程代码块
        printf("\n子进程运行中 (PID: %d)\n", getpid());
        
        // 2. exec()示例 - 执行ls命令
        printf("准备执行ls命令...\n");
        execl("/bin/ls", "ls", "-l", NULL);
        
        // 如果exec执行成功,以下代码不会运行
        perror("exec失败");
        return 1;
    } else {
        // 父进程代码块
        printf("\n父进程 (PID: %d) 创建了子进程 (PID: %d)\n", 
               getpid(), pid);
        
        // 3. wait()示例
        printf("父进程等待子进程结束...\n");
        int status;
        wait(&status);
        
        if (WIFEXITED(status)) {
            printf("\n子进程退出状态: %d\n", WEXITSTATUS(status));
        }
    }

    printf("程序执行结束\n");
    return 0;
}

按ESC键退出编辑模式,输入:wq保存并退出vi。

3.1.5使用gcc编译和运行程序

gcc process.c -o week6//prcess.c为创建的c文件名称 week6为之前创建的子目录名称
./week6

运行结果如下:

3.2在各小组的树莓派中,也手动创建组员的账号,组员在各自的账号+home目录下,完成同样的Linux系统调用函数练习。

3.2.1登录树莓派,打开端口进行账号密码的创建

创建组

sudo groupadd team//team为组的名称

创建账号

sudo useradd -m -G team -s /bin/bash maxy//maxy为创建的用户名称

设置对应账户的密码

echo "member1:password1"//member1为设置密码的用户名称 password1为要设置的密码

3.2.2登录对应账号后进行编辑程序然后运行

登录账号

ssh member1@树莓派IP地址
# 输入密码password1

创建子目录

mkdir test//创建子目录 test为创建子目录的名称
cd test//登录子目录

编辑程序代码

nano week6.c//week6.c为文件的名称

输入代码

// process_demo.c
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>

int main() {
    printf("[%d] Parent process starts\n", getpid());

   
    pid_t pid = fork();

    if (pid < 0) {
        perror("Fork failed");
        return 1;
    } 
    else if (pid == 0) {
   
        printf("[%d] Child process running\n", getpid());
        
       
        execl("/bin/ls", "ls", "-l", NULL);
        
       
        perror("Exec failed");
        return 1;
    } 
    else {
       
        printf("[%d] Parent waiting for child %d\n", getpid(), pid);
        
    
        int status;
        wait(&status);
        
        if (WIFEXITED(status)) {
            printf("[%d] Child exited with status %d\n", 
                  getpid(), WEXITSTATUS(status));
        }
    }

    printf("[%d] Process ends\n", getpid());
    return 0;
}

编译程序

gcc -Wall -Wextra week6.c -o test//week6.c为程序代码的文件名称 test为前面创建的子目录

运行程序

./test//./为运行 test为运行文件的子目录

运行成功

相关文章:

  • LeetCode102.二叉树的层序遍历
  • 【操作系统】Linux进程管理和调试
  • QML Book 学习基础6(定位/布局元素)
  • 【浏览器的渲染原理】
  • uniapp微信小程序开发工具本地获取指定页面二维码
  • 【AI工具】DeepSeek直接生成图片,效果不错
  • 前后端数据序列化:从数组到字符串的旅程(附优化指南)
  • 爬虫:请求头,requests库基本使用
  • 《C++Linux编程进阶:从0实现muduo 》-第8讲.C++面试如何高效获取线程ID
  • nginx如何重启
  • 物联网时代,HMI 设计的创新机遇与挑战
  • 人工智能的三个主义(行为主义、连结主义、符号主义)的整体性关系(并非割裂)
  • MySQL注入中user-agent和cookie存在的注入
  • OpenCV 从入门到精通(day_03)
  • 化学方程式配平 第33次CCF-CSP计算机软件能力认证
  • WEB安全--文件上传漏洞--黑名单绕过
  • 《Linux运维总结:基于银河麒麟V10操作系统+ARM64架构CPU二进制部署单机ACL版consul v1.18.1》
  • 【linux】管理磁盘——RAID10(含备份)与逻辑卷管理
  • Java线程池详解
  • 用deepseek创建可运行的简单的php框架
  • 辽宁援疆前指总指挥王敬华已任新疆塔城地委副书记
  • 张巍任中共河南省委副书记
  • 收到延期付款利息,该缴纳增值税吗?
  • 国防部:赖清德歪曲二战历史,背叛民族令人不齿
  • 押井守在30年前创造的虚拟世界何以比当下更超前?
  • 张涌任西安市委常委,已卸任西安市副市长职务