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

做网站需要什么人才如何做学校网站

做网站需要什么人才,如何做学校网站,自助建站免费永久,seo一个月赚多少钱一. 进程概述:进程(Process)是操作系统中资源分配和调度的基本单位,是正在运行的程序的实例。每个进程拥有独立的地址空间、代码、数据和系统资源(如打开的文件、内存、CPU时间等)。进程之间相互独立&#…

一. 进程

概述:

进程(Process)是操作系统中资源分配和调度的基本单位,是正在运行的程序的实例。每个进程拥有独立的地址空间、代码、数据和系统资源(如打开的文件、内存、CPU时间等)。进程之间相互独立,通常通过操作系统提供的机制(如进程间通信IPC)进行交互。进程的生命周期包括创建、运行、等待、就绪和终止等状态。

简而言之:进程是操作系统对正在运行程序的管理方式,概括为进程是运行的程序

C语言中:

c语言中,main函数运行后就是一个进程,程序中所有的调度都是通过main来实现。

windows进程:(win+alt+.)

linux进程 

ps aux / ps -ef 

 top / htop

二. 进程的操作:

1. 创建进程

特性:
特性fork()vfork()
内存复制采用写时复制 (Copy-On-Write)完全不复制父进程地址空间
执行顺序父子进程执行顺序不确定父进程阻塞直到子进程退出或 exec
地址空间子进程获得独立地址空间子进程共享父进程地址空间
性能开销较高(需复制页表等元数据)极低(无内存复制开销)
安全性安全(内存隔离)危险(子进程可破坏父进程内存)
 特点:
函数标准特点最佳场景
fork()POSIX安全但开销大通用进程创建
vfork()POSIX高效但危险立即exec的极端优化场景
posix_spawn()POSIX.1d安全高效的exec封装便携式高效进程创建
clone()Linux可定制共享资源的轻量级进程线程/特殊IPC场景
pthread_create()POSIX纯用户态线程创建多线程并发
差异:
维度fork()vfork()
调度顺序父子进程并行执行
• 谁先运行由调度器决定
严格串行化
• 父进程被强制挂起
• 子进程完全执行完毕(或调用exec/exit)后父进程才恢复
退出要求子进程可自由退出(exitreturn子进程必须立即调用 exec()_exit()
• 禁止从函数返回(会破坏父进程栈)
• 禁止使用exit()(会刷新共享I/O缓冲区)
阻塞行为父进程不会被阻塞父进程在 vfork() 调用处阻塞等
1. fork
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h> // 添加头文件以使用 strlen 函数int main(int argc, char const *argv[])
{int id = getpid(); // 获取当前进程的ID// 1.fork() 创建子进程pid_t pid = fork();if (pid < 0){// pid<0,代表创建失败printf("Fork failed.\n");exit(EXIT_FAILURE);}else if (pid == 0){// 子进程printf("这是子进程,子id = %d,父id = %d\n", id, getppid(), getppid()); // 获取父进程ID}else{// 父进程printf("这是父进程%d\n", id);}return 0;
}

2. vfork
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h> // 添加头文件以使用 strlen 函数int main(int argc, char const *argv[])
{// 1.vfork() 创建子进程pid_t pid = vfork();if (pid < 0){// pid<0,代表创建失败printf("vFork failed.\n");exit(EXIT_FAILURE);}else if (pid == 0){// 子进程printf("这是子进程,子id = %d,父id = %d\n", getpid(), getppid()); // 获取父进程ID_exit(0);                                                        // 使用_exit()而不是exit(),避免影响父进程的状态}else{// 父进程printf("这是父进程%d\n", getpid()); // 获取当前进程的ID}return 0;
}

3. clone / posix_spawn(不讲,有时间写)

2. 生命周期

1. 流程图

2. 概述 

1. 创建状态 (New)
  • 本质:进程正在被创建

  • 触发动作:系统调用(如 fork(), vfork()

  • 关键操作

    • 分配进程控制块(PCB)

    • 初始化进程数据结构

    • 分配初始资源(PID、优先级等)

  • 持续时间:瞬时状态(微秒级)


2. 就绪状态 (Ready)
  • 本质:具备运行条件,等待CPU分配

  • 进入条件

    • 进程创建完成

    • 阻塞状态结束(如I/O完成)

    • 时间片到期被剥夺CPU

  • 核心特征

    • 位于就绪队列排队

    • 只缺CPU资源

    • 可随时被调度器选中


3. 运行状态 (Running)
  • 本质:正在CPU上执行指令

  • 触发条件:被调度器选中

  • 关键行为

    • 占用CPU执行代码

    • 可能触发状态转换:

      • 时间片用完 → 回到就绪态

      • 请求资源 → 进入阻塞态

      • 执行结束 → 进入终止态

  • 持续时间:纳秒到毫秒级(取决于时间片)


4. 阻塞状态 (Blocked/Waiting)
  • 本质:等待外部事件完成

  • 常见触发原因

    • I/O操作请求(磁盘/网络)

    • 获取互斥锁失败

    • 等待信号量

    • 定时等待(如sleep()

  • 核心特征

    • 主动让出CPU

    • 移出就绪队列

    • 资源满足后自动回就绪态


5. 终止状态 (Terminated)
  • 本质:进程执行结束

  • 触发条件

    • 正常结束(执行完毕)

    • 异常终止(收到终止信号)

    • 被父进程终止

  • 关键操作

    • 释放所有资源(内存、文件、设备)

    • PCB保留退出状态(供父进程查询)

    • 最终从系统移除

3. 代码展示 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>int main(int argc, char const *argv[])
{// 进程的生命周期// 1.创建状态pid_t pid = vfork(); // 使用 vfork 创建子进程printf("创建状态.............");// 2.就绪状态printf("就绪状态.............");if (pid == 0){// 3.运行状态printf("运行状态.............");printf("这是子进程,子id = %d,父id = %d\n", getpid(), getppid());// 4.阻塞状态printf("阻塞状态.............");sleep(5); // 模拟阻塞状态,等待5秒// 5.结束状态(销毁)printf("子进程结束.............");_exit(0); // 使用 _exit() 结束子进程,避免影响父进程的状态}else if (pid > 0){// 父进程printf("父进程.............");}else{// 创建失败perror("vfork failed");exit(EXIT_FAILURE);}return 0;
}

3. 进程替换 (不太明白)

进程替换(Process Replacement)是 Unix/Linux 系统中一种核心机制,它允许正在运行的进程完全替换自身,转而执行一个全新的程序。这一机制通过 exec 系列函数实现,是操作系统动态性的关键体现。

即,此进程完全复制前一个进程,但保留此进程的pid。

1. 本质与特点
特性说明
原地替换不创建新进程,保留原进程的 PID、父进程关系、文件描述符等属性
内存重构完全替换地址空间(代码段、数据段、堆栈)
无返回成功执行后永不返回原程序(函数无返回值)
效率优势避免创建新进程的开销(无需复制页表/内存)
2. exec 函数家族
函数参数风格环境变量PATH搜索典型使用场景
execl()参数列表继承固定参数的可执行程序
execv()指针数组继承动态生成参数的场景
execlp()参数列表继承Shell命令执行
execvp()指针数组继承执行用户输入的命令
execle()参数列表自定义需要特定环境变量的程序
execve()指针数组自定义系统级编程(实际系统调用)
fexecve()指针数组自定义通过文件描述符指定程序(Linux特有)
📌 底层真相:所有函数最终都调用 execve() 系统调用(内核入口)
 3. 代码解释
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>int main(int argc, char const *argv[])
{// 进程替换pid_t pid = fork();if (pid == 0){// 子进程execlp("ls", "ls", "-l", NULL);perror("替换失败");_exit(1);}else if (pid > 0){// 父进程wait(NULL);}else{// 创建失败perror("创建失败");exit(EXIT_FAILURE);}return 0;
}

总结:进程替换的本质

进程替换不是创建新进程,而是进程的重生

  1. 保留外壳(PID、资源)

  2. 替换核心(程序代码)

  3. 重置状态(信号、寄存器)

  4. 重获新生(从新入口执行)

4. 进程通信

管道

本质与类型
  • 无名管道int pipe(int fd[2])

    • 内核中的循环缓冲区(默认 64KB)

    • 单向数据流:fd[0] 只读,fd[1] 只写

    • 生命周期随进程结束

  • 有名管道mkfifo()

    • 文件系统节点(inode 标识)

    • 允许无亲缘关系进程通信

特性无名管道有名管道
创建方式pipe()mkfifo()
文件系统路径有(如 /tmp/fifo
进程关系必须亲缘关系任意进程
生命周期随进程结束销毁显式调用 unlink() 删除
打开行为直接使用文件描述符open(),可能阻塞
持久性临时持久(除非删除)
典型用途Shell 管道、父子进程通信无亲缘关系进程间通信
区别于IO流
特性有名管道 (FIFO)普通文件I/O流
物理存储无磁盘存储
数据仅在内核缓冲区中
数据持久化存储到磁盘
数据生命周期读取后立即消失永久存储,可重复读取
访问方式严格遵循FIFO顺序支持随机访问(lseek
打开行为需要成对进程打开(读写端)否则阻塞单进程可独立读写
存储机制内核维护的循环缓冲区文件系统分配的磁盘块
最大容量管道缓冲区大小(默认64KB)仅受磁盘空间限制
原子性保证写操作≤PIPE_BUF(4KB)时原子无内置原子性保证
1. 无名管道
  • 使用 pipe(int pipefd[2]) 系统调用创建

  • 无文件系统路径,仅通过文件描述符pipefd[0]读端,pipefd[1]写端)访问

int pipefd[2];
pipe(pipefd); // 创建无名管道
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h> // 添加头文件以使用 strlen 函数
#include <locale.h>/*** pipe 管道,用于进程之间通信(父子进程)*/
int main(int argc, char const *argv[])
{setlocale(LC_ALL, ""); // 使程序使用系统 locale,支持中文utf-8// 1.创建无名管道int fd[2];// 创建管道if (pipe(fd) == -1){perror("pipe");exit(EXIT_FAILURE);}// 2.创建子进程pid_t pid = fork();if (pid < 0){perror("fork");exit(EXIT_FAILURE);}else if (pid == 0){// 子进程close(fd[1]); // 关闭写端char buffer[100];read(fd[0], buffer, sizeof(buffer)); // 从管道读取数据printf("Child process received: %s\n", buffer);close(fd[0]); // 关闭读端exit(EXIT_SUCCESS);}else{// 父进程close(fd[0]); // 关闭读端const char *message = "这是父进程发送的消息";write(fd[1], message, strlen(message) + 1); // 向管道写入实际字符串长度+1(包含结尾\0)close(fd[1]);                               // 关闭写端}return 0;
}
2.有名管道
  • 使用 mkfifo(const char *pathname, mode_t mode) 创建

  • 在文件系统中有一个路径名(如 /tmp/myfifo),像普通文件一样存在

mkfifo("/tmp/myfifo", 0666); // 创建有名管道
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>/*有名管道*/
int main(int argc, char const *argv[])
{// 1.创建有名管道const char *fifo_path = "/tmp/my_fifo";mkfifo(fifo_path, 0666);// 2.创建子进程pid_t pid = fork();if (pid == 0){// 子进程:写入数据int fd = open(fifo_path, O_WRONLY);write(fd, "Hello from child", 17);close(fd);exit(0);}// 3.父进程:读取数据char buffer[100];int fd = open(fifo_path, O_RDONLY);read(fd, buffer, sizeof(buffer));printf("父进程读取到:%s\n", buffer);close(fd);// 4.清理unlink(fifo_path);return 0;
}

信号(Signal)

本质与类型
  • 软件中断:异步事件通知机制

  • 标准信号:如 SIGINT (Ctrl+C), SIGKILL (强制终止)

  • 实时信号:支持排队

 

system v ipc

消息队列

信号量

即,信号量即是一种状态,我如果让他,一次性等于五,他会让五个进程去操作内存,如果一共,有十个,剩余的五个则等待,进入的五个进程依次退出,剩下的五个依次进入.

  1. 计数器: 信号量本质上是一个非负整数的计数器。

  2. 操作: 对信号量的操作主要是两个原子操作(Atomic Operation):

    • P 操作 (Wait/Sleep/Down):

      • 尝试将信号量的值减 1。

      • 如果信号量值大于 0,则减 1 并立即返回(进程获得资源)。

      • 如果信号量值等于 0,则进程(或线程)会被阻塞(休眠),直到信号量值变为大于 0(有别的进程释放资源),然后它才能成功执行减 1 操作并继续执行。

    • V 操作 (Signal/Post/Up):

      • 将信号量的值加 1。

      • 如果有进程因为在该信号量上执行 P 操作而被阻塞,V 操作会唤醒其中一个(或多个,取决于实现)被阻塞的进程。

  3. 目的: 信号量用来表示可用资源的数量。P 操作代表申请一个资源,V 操作代表释放一个资源。当信号量初始化为 1 时,它就变成了一个互斥锁(Mutex),用于保证同一时刻只有一个进程可以访问临界区。

  4. 进程间信号量: 我们讨论的信号量驻留在内核中,由内核维护其状态和阻塞队列。因此,不同的进程可以通过同一个信号量的标识符(key 或 name)来访问和操作它,实现跨进程的同步。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <semaphore.h>#define TOTAL_PROCS 10
#define ALLOWED_AT_ONCE 5
#define SEM_NAME "/my_semaphore_example"void child_process(int id)
{// 打开已存在的信号量sem_t *sem = sem_open(SEM_NAME, O_RDWR);if (sem == SEM_FAILED){perror("子进程信号量打开失败");exit(1);}printf("子进程 %d (PID:%d) 等待进入...\n", id, getpid());// P操作:等待通行证sem_wait(sem);// 临界区开始printf("✅ 子进程 %d (PID:%d) 进入临界区\n", id, getpid());sleep(2); // 模拟工作printf("🚪 子进程 %d (PID:%d) 离开临界区\n", id, getpid());// 临界区结束// V操作:归还通行证sem_post(sem);sem_close(sem);exit(0);
}int main()
{// 创建信号量 (初始5张通行证)sem_t *sem = sem_open(SEM_NAME, O_CREAT | O_RDWR, 0666, ALLOWED_AT_ONCE);if (sem == SEM_FAILED){perror("信号量创建失败");exit(1);}printf("主进程 (PID:%d) 启动,创建 %d 个子进程,信号量容量: %d\n",getpid(), TOTAL_PROCS, ALLOWED_AT_ONCE);// 创建子进程for (int i = 0; i < TOTAL_PROCS; i++){pid_t pid = fork();if (pid == 0){child_process(i + 1); // 子进程执行exit(0);}}// 等待所有子进程结束for (int i = 0; i < TOTAL_PROCS; i++){wait(NULL);}// 清理sem_close(sem);sem_unlink(SEM_NAME); // 删除信号量printf("\n所有子进程完成!信号量已清理\n");return 0;
}
http://www.dtcms.com/a/448190.html

相关文章:

  • 如何自己设计创建一个网站建湖做网站价格
  • 创立一个网站需要什么wordpress相关知识
  • 威联通怎么建设网站域名注册查询阿里云
  • 门户网网站建设功能需求表江西做网站优化好的
  • 做酒的网站外加工网
  • 注销主体备案与网站备案表凡科建站后台登录
  • 做赌场网站犯法么北京网站建设及app
  • 请人建网站应注意什么室内设计可以去哪些公司
  • 凡科建站怎么做微网站python基础教程网易
  • 网站升级改版需要多久成都住建局官网查询结果在线验证
  • 门户网站系统程序徐州网站建设 徐州网站推广
  • 澄海建网站哈尔滨模板建站定制网站
  • 泰安网站建设收费标准wordpress 升级主题
  • 网站文章要求如何做外贸网店
  • 池州商城网站开发网站图片修改
  • 江门网站制作开发廊坊seo排名优化
  • 高毅资产网站谁做的近期舆情热点事件
  • 装修平台网站有哪些网站的线下推广怎么做
  • 童装 技术支持 东莞网站建设网络营销的优势包括
  • 城市建设法规考试网站网络推广的工作好做吗
  • asp网站知道用户名是admin安阳县崔家桥职业中专
  • 河南网站建设怎么收费济南做网站个人
  • 行业网站导航站长工具网址查询
  • 中国视觉设计网站网站导航包括
  • 河南新乡做网站公司紧急大通知狼拿笔记好
  • 做网站的内容样本办一家建筑公司流程
  • 做阿里网站卖东西赚钱动态可视化excel图表制作
  • 服装网站建设平台企业做网站被骗
  • 动力 网站建设wordpress删除页面地址
  • 2018做网站还没有做网站可以先备案域名吗