系统调用 , 进程

This commit is contained in:
flykhan 2023-08-15 19:05:13 +08:00
parent 23d395c790
commit ef704ce9f1
13 changed files with 429 additions and 0 deletions

21
day2/d1.c Normal file
View File

@ -0,0 +1,21 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
// 修改标准的输入设备的标识为非阻塞
int flags = fcntl(STDIN_FILENO, F_GETFL);
flags |= O_NONBLOCK; // 添加非阻塞标识,可以注释这一行来测试不同的效果
fcntl(STDIN_FILENO, F_SETFL, flags);
char buf[32] = "";
printf("准备读取数据......\n");
// read 默认是阻塞的,如果没有数据,会一直等待
// 接收到一个回车read就会返回
ssize_t len = read(STDIN_FILENO, buf, sizeof(buf));
printf("读取的内容为:%s\n", buf);
return 0;
}

52
day2/d2.c Normal file
View File

@ -0,0 +1,52 @@
// 使用系统调用实现cp命令
// 1. 打开源文件
// 2. 创建目标文件
// 3. 循环读取源文件,写入目标文件
// 4. 关闭文件
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
int srcfd, dstfd;
char buf[1024];
int len;
if (argc < 3)
{
printf("./a.out srcfile dstfile\n");
exit(1);
}
// 打开源文件
srcfd = open(argv[1], O_RDONLY);
if (srcfd < 0)
{
perror("open");
exit(1);
}
// 创建目标文件
dstfd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0664);
if (dstfd < 0)
{
perror("open");
exit(1);
}
// 循环读取源文件,写入目标文件
while ((len = read(srcfd, buf, sizeof(buf))) > 0)
{
write(dstfd, buf, len);
}
// 关闭文件
close(srcfd);
close(dstfd);
return 0;
}
// ./a.out srcfile dstfile

27
day2/d3.c Normal file
View File

@ -0,0 +1,27 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
// 使用 stat 函数获取文件的信息,并判断文件类型
int main(int argc, char const *argv[])
{
const char *path = argv[1]; // 获取命令行参数中的文件路径
struct stat fileStat;
if (stat(path, &fileStat) == 0)
{
// 获取文件信息成功
if (fileStat.st_mode & __S_IFDIR)
{
printf("%s 是一个目录\n", path); // 判断文件是否为目录,并输出相应信息
}
else if (fileStat.st_mode & __S_IFREG)
{
printf("%s 是一个普通文件\n", path); // 判断文件是否为普通文件,并输出相应信息
}
}
return 0; // 返回成功码
}

17
day2/d4.c Normal file
View File

@ -0,0 +1,17 @@
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
printf("正在运行程序,进程号: %d\n", getpid());
while (1)
;
return 0;
}
/*
ps -ef | grep a.out
kill -9
*/

48
day2/d5.c Normal file
View File

@ -0,0 +1,48 @@
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
int n = 100;
int total = 0;
// 父进程完成 给定的整数以内的 3 的倍数的和
// 子进程完成 给定的整数以内的 5 的倍数的和
pid_t pid = fork();
if (pid < 0)
{
perror("fork error");
return -1; // fork 出错, 退出
}
if (pid == 0)
{
// 子进程
for (int i = 1; i <= n; i++)
{
if (i % 5 == 0)
{
total += i;
}
}
printf("子进程(%d) : 1-%d 以内的 5 的倍数的和为: %d\n", getpid(), n, total);
}
else
{
// 父进程
for (int i = 1; i <= n; i++)
{
if (i % 3 == 0)
{
total += i;
}
}
printf("父进程(%d): 1-%d 以内的 3 的倍数的和为: %d\n", getpid(), n, total);
}
printf("进程(%d) 退出\n", getpid());
// while (1)
// ;
return 0;
}

13
day2/d6.c Normal file
View File

@ -0,0 +1,13 @@
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
printf("%d fork before\n", getpid()); // 向缓冲区写入数据
int pid = fork();
// int pid2 = fork();
// int pid3 = fork();
// printf("%d fork after\n", getpid()); // 向缓冲区写入数据
return 0;
}

18
day2/d7.c Normal file
View File

@ -0,0 +1,18 @@
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <time.h>
int main(int argc, char const *argv[])
{
time_t at = time(NULL);
char buf[32] = "";
sprintf(buf, "%d 运行中", getpid());
write(1, buf, sizeof(buf));
sleep(2);
time_t bt = time(NULL);
printf("\n%d 结束\n", getpid());
printf("运行时间:%ld 秒\n", bt - at);
return 0;
}

43
day2/d8.c Normal file
View File

@ -0,0 +1,43 @@
#include <stdio.h> // perror
#include <sys/types.h> // pid_t
#include <unistd.h> // fork
#include <sys/wait.h> // wait
int main(int argc, char const *argv[])
{
int pid = fork();
if (pid < 0)
{
perror("fork");
return -1;
}
if (pid == 0)
{
// write(1, "123", 4);
int n = 10 / 0;
sleep(3);
printf("%d 子进程结束", getpid());
return 10;
}
else
{
// status 用来保存子进程的退出状态
int status;
int pid = wait(&status); // 等待子进程结束
printf("\n%d 父进程中, 等到了子进程 %d 结束, status = %d \n", getpid(), pid, status >> 8);
// WIFEXITED(status) 为真表示子进程正常退出
if (WIFEXITED(status) & 0xff00 >> 8) // 子进程是否正常退出
{
// WEXITSTATUS(status) 获取子进程的退出码
printf("%d", WEXITSTATUS(status));
}
else
{
printf("子进程异常退出, status = %d", status >> 8);
}
}
return 0;
}

42
day2/d9.c Normal file
View File

@ -0,0 +1,42 @@
#include <stdio.h> // perror
#include <sys/types.h> // pid_t
#include <unistd.h> // fork
#include <sys/wait.h> // wait
int main(int argc, char const *argv[])
{
int pid = fork();
if (pid < 0)
{
perror("fork");
return -1;
}
if (pid == 0)
{
printf("%d 子进程准备睡眠 3 秒\n", getpid());
sleep(3);
printf("%d 子进程结束", getpid());
return 10;
}
else
{
// status 用来保存子进程的退出状态
int status;
int pid2 = waitpid(pid, &status, WUNTRACED); // 等待子进程结束
printf("\n%d 父进程中, 等到了子进程 %d 结束, status = %d \n", getpid(), pid, status >> 8);
// WIFEXITED(status) 为真表示子进程正常退出
if (WIFEXITED(status) & 0xff00 >> 8) // 子进程是否正常退出
{
// WEXITSTATUS(status) 获取子进程的退出码
printf("%d", WEXITSTATUS(status));
}
else
{
printf("子进程异常退出, status = %d", status >> 8);
}
}
return 0;
}

32
day2/test_fork.c Normal file
View File

@ -0,0 +1,32 @@
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
pid_t pid;
pid = fork(); // 创建一个子进程
if (pid < 0)
perror("fork"); // 如果 fork 失败,打印错误信息
if (pid == 0)
{
// 子进程代码
while (1)
{
printf("这是子进程\n");
sleep(1); // 休眠 1 秒
}
}
else
{
// 父进程代码
while (1)
{
printf("这是父进程\n");
sleep(1);
}
}
return 0;
}

57
day2/test_fork2.c Normal file
View File

@ -0,0 +1,57 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
static int vax = 18; // 静态全局变量
int var = 10; // 全局变量
int main(int argc, char const *argv[])
{
pid_t pid;
int num = 9; // 局部变量
pid = fork(); // 创建子进程
if (pid < 0)
{
perror("fork");
}
if (pid == 0) // 子进程
{
vax--; // 子进程中修改静态全局变量 vax
var++; // 子进程中修改全局变量 var
num++; // 子进程中修改局部变量 num
printf("在子进程的 vax=%d, var=%d, num=%d\n", vax, var, num);
}
else // 父进程
{
sleep(1); // 父进程等待一秒钟
printf("在父进程的 vax=%d, var=%d, num=%d\n", vax, var, num);
}
printf("命令代码区\n"); // 在父进程和子进程中都会执行的代码
return 0;
}
/*
var num
var 10 num 9
fork()
fork() ID pid 0
sleep(1)
fork() 0
var++ var 1num++ num 1
"在子进程的 var=11, num=10"
"在父进程的 var=10, num=9"
"命令代码区"
*/
/*
fork()
var 11 num 10 var 10 num 9
"命令代码区" fork()
*/

38
day2/test_fork3.c Normal file
View File

@ -0,0 +1,38 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
int main(int argc, char const *argv[])
{
pid_t pid;
int length = 0;
char buf[] = "a write to stdout\n";
// 向标准输出写入数据 1 表示标准输出
length = write(1, buf, strlen(buf));
if (length != strlen(buf))
{
printf("写入错误\n");
}
printf("fork之前\n");
pid = fork(); // 创建子进程
if (pid < 0)
{
perror("fork"); // 输出错误信息
}
else if (pid == 0) // 子进程
{
printf("在子进程中\n");
}
else // 父进程
{
sleep(1); // 等待1秒钟
printf("在父进程中\n");
}
printf("fork之后\n");
return 0;
}

21
day2/test_pid.c Normal file
View File

@ -0,0 +1,21 @@
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
// 进程号,父进程号,组进程号
pid_t pid, ppid, pgid;
pid = getpid(); // 获取当前进程的进程号
ppid = getppid(); // 获取当前进程的父进程号
// pgid = __getpgid(0); // 获取当前进程所属的组进程号
pgid = getpgid(ppid);
printf("pid = %d\nppid = %d\npgid = %d\n", pid, ppid, pgid);
while (1)
;
return 0;
}