系统调用 , 进程
This commit is contained in:
parent
23d395c790
commit
ef704ce9f1
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -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; // 返回成功码
|
||||||
|
}
|
|
@ -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 进程号 杀死进程
|
||||||
|
*/
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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 的值加1,num++ 将局部变量 num 的值加1。
|
||||||
|
子进程打印输出 "在子进程的 var=11, num=10"。
|
||||||
|
父进程等待一秒钟后恢复执行,继续执行下面的代码。
|
||||||
|
父进程打印输出 "在父进程的 var=10, num=9"。
|
||||||
|
打印输出 "命令代码区"。
|
||||||
|
程序结束。
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
由于 fork() 创建了一个子进程,子进程会复制父进程的内存空间,包括变量的值。因此,父进程和子进程拥有各自独立的变量副本,它们的修改互不影响。
|
||||||
|
|
||||||
|
在子进程中,变量 var 的值被增加到 11,而变量 num 的值被增加到 10。在父进程中,变量 var 保持为初始值 10,变量 num 保持为初始值 9。这说明父进程和子进程中的变量是独立的。
|
||||||
|
|
||||||
|
最后的打印输出语句 "命令代码区" 在父进程和子进程中都会执行,因为它们是在 fork() 调用之前执行的代码。
|
||||||
|
*/
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
Loading…
Reference in New Issue