学校里开设的稍微有点用的一节课,所有代码均在ubuntu20.04下测试成功。
文件操作
1、利用creat()、open()和close()函数进行系统调用,实现创建、打开和关闭一个文件。 (1)以可读写方式新建并关闭一个文件“stu.txt”,如果成功则返回新建文件的文 件名,不成功则输出错误提示信息。 (2) 以可读写方式打开并关闭一个文件“file.txt”,如果成功则返回文件的文件名, 不成功则输出错误提示信息。
1#include <sys/stat.h>
2#include <fcntl.h>
3#include <unistd.h>
4#include <stdio.h>
5
6int main()
7{
8 const char *stufilename = "stu.txt";
9 int stufd = creat(stufilename, S_IRWXG);
10 if (stufd == -1)
11 {
12 printf("%s creat failed\n", stufilename);
13 }
14 close(stufd);
15
16 const char *filename = "file.txt";
17 int filefd = open(filename, O_RDWR | O_CREAT | O_TRUNC, 0777);
18 if (filefd == -1)
19 {
20 printf("%s open failed!\n", filename);
21 }
22
23 return 0;
24}
2、编程实现一个简单的学生信息管理程序: (1)从键盘输入3个学生信息(学号、姓名、年龄),存放于结构体数组中,将结 构体写入文件“stu.txt”中。 (2)从键盘输入某个学生的学号,从“stu.txt”文件中读出指定学号的学生的全部 信息并显示。 (3) 实现人机交互操作:可以循环查询并显示查询结果,直到用户不再操作,结 束程序运行。
1#include <fcntl.h>
2#include <unistd.h>
3#include <stdio.h>
4#include <stdbool.h>
5
6typedef struct
7{
8 int id;
9 char name[50];
10 int age;
11} Student;
12
13const char *StuFileName = "./stu.txt";
14
15int inputStudents(int fd, int count);
16int searchStudent(int fd, int id, int count);
17
18int main()
19{
20 int stufd = open(StuFileName, O_RDWR | O_CREAT | O_TRUNC, 0777);
21 if (stufd == -1)
22 {
23 printf("%s creat failed\n", StuFileName);
24 return 0;
25 }
26
27 int inre = inputStudents(stufd, 3);
28 if (inre == -1)
29 {
30 printf("写入失败\n");
31 }
32
33 while (true)
34 {
35 int id;
36 printf("请输入要查找的学生id(输入-1退出):");
37 scanf("%d", &id);
38 if (id == -1)
39 break;
40
41 int sere = searchStudent(stufd, id, 3);
42 if (inre == -1)
43 {
44 printf("查找失败\n");
45 }
46 }
47
48 close(stufd);
49
50 return 0;
51}
52
53int inputStudents(int fd, int count)
54{
55 Student student;
56 for (int i = 0; i < count; i++)
57 {
58 printf("输入第 %d 个学生的信息:\n", i + 1);
59 printf("学号:");
60 scanf("%d", &student.id);
61 printf("姓名:");
62 scanf("%s", student.name);
63 printf("年龄:");
64 scanf("%d", &student.age);
65
66 off_t fdof = lseek(fd, i * sizeof(student), SEEK_SET);
67 if (fdof == -1)
68 return -1;
69
70 if (write(fd, &student, sizeof(student)) == -1)
71 {
72 printf("write err\n");
73 return -1;
74 }
75 }
76
77 off_t fdof = lseek(fd, 0, SEEK_SET);
78 if (fdof == -1)
79 return -1;
80
81 return 0;
82}
83
84int searchStudent(int fd, int id, int count)
85{
86 Student student;
87 for (int i = 0; i < count; i++)
88 {
89 off_t fdof = lseek(fd, i * sizeof(student), SEEK_SET);
90 if (fdof == -1)
91 return -1;
92 if (read(fd, &student, sizeof(student)) == -1)
93 {
94 printf("read err\n");
95 return -1;
96 }
97
98 if (student.id == id)
99 {
100 printf("查找到:\n");
101 printf("姓名:%s\n", student.name);
102 printf("年龄:%d\n", student.age);
103 }
104 }
105
106 if (student.id != id) {
107 printf("未查找到!\n");
108 }
109
110 off_t fdof = lseek(fd, 0, SEEK_SET);
111 if (fdof == -1)
112 return -1;
113
114 return 0;
115}
进程创建
1、使用fork()函数循环创建n个子进程(n≥2),并显示每个子进程的进程号以 及其父进程的进程号。
1#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <fcntl.h>
5#include <sys/wait.h>
6
7void create_processes(int n)
8{
9 for (int i = 0; i < n; i++)
10 {
11 pid_t pid = fork();
12 if (pid < 0)
13 {
14 printf("进程创建失败");
15 exit(1);
16 }
17 else if (pid == 0)
18 {
19 printf("创建成功,子进程 PID: %d, 父进程 PID: %d\n", getpid(), getppid());
20 exit(0);
21 }
22 }
23
24 for (int i = 0; i < n; i++)
25 {
26 wait(NULL);
27 }
28}
29
30int main()
31{
32 int n = 0;
33 printf("需要创建进程的数量:");
34 scanf("%d", &n);
35 create_processes(n);
36 return 0;
37}
2、使用fork()函数创建一个子进程,在子进程中使用execl()函数执行ls命令 (ls命令的参数自定),并在屏幕上显示“任务完成!”提示。
1#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <fcntl.h>
5#include <sys/wait.h>
6#include<sys/types.h>
7#include<stdbool.h>
8
9void create_processes(int n)
10{
11 for (int i = 0; i < n; i++)
12 {
13 pid_t pid = fork();
14 if (pid < 0)
15 {
16 printf("进程创建失败");
17 exit(1);
18 }
19 else if (pid == 0)
20 {
21 printf("子进程%d,开始执行ls -l\n", getpid());
22 execl("/bin/ls", "ls", "-l", NULL);
23 exit(0);
24 }
25 int status = 0;
26
27 waitpid(pid, &status, 0);
28 bool a = WIFEXITED(status);
29 if (a) {
30 printf("子进程%d,执行ls -l成功\n", pid);
31 }
32 }
33
34 for (int i = 0; i < n; i++)
35 {
36 wait(NULL);
37 }
38}
39
40int main()
41{
42 int n = 0;
43 printf("需要创建进程的数量:");
44 scanf("%d", &n);
45 create_processes(n);
46 return 0;
47}
3、使用system()函数顺序执行以上两个可执行程序。
1#include <stdio.h>
2#include <stdlib.h>
3
4int main() {
5 system("./create_process");
6 system("./execute_ls");
7 return 0;
8}
进程间通信
1、在主程序中用pipe()创建一个管道,用fork()创建一个子进程,其父进程接收 从键盘输入一个字符串,并写入管道中;子进程从管道中读取该字符串,显示信息如下: ①统计字符串中字符的个数,并显示; ②显示字符串内容。
1#include<stdio.h>
2#include<string.h>
3#include<unistd.h>
4#include<sys/types.h>
5
6#define ERR -1
7
8int main(void)
9{
10 int res = ERR;
11 int fd[2], nbytes;
12
13 int *write_fd = &fd[1];
14 int *read_fd = &fd[0];
15
16 res = pipe(fd);
17
18 if (res == ERR)
19 {
20 printf("创建管道失败!");
21 return ERR;
22 }
23
24 pid_t pid = fork();
25
26 if (pid == ERR)
27 {
28 printf("创建子进程失败!");
29 return -1;
30 }
31
32 if (pid == 0)
33 {
34 close(*read_fd);
35 char string[100];
36 printf("向子进程写入:");
37 scanf("%s", string);
38 write(*write_fd, string, strlen(string));
39 }
40 else
41 {
42 close(*write_fd);
43 char readbufffer[100];
44 ssize_t num = read(*read_fd, readbufffer, sizeof(readbufffer));
45 printf("子进程(pid=%d),接收到%ld字节数据: %s\n", pid, num, readbufffer);
46 }
47
48 return 0;
49}
2、编写两个程序,程序1接收到SIGUSR1信号时显示一行信息:“sigusr1 signal received!”,程序2每隔2秒钟发送一个SIGUSR1信号给程序1。 注意:该题由两个程序组成,需要在两个窗口分别运行。运行顺序:首先运行程序1,因为在程序1中需要编写接收SIGUSR1信号函数,并得到父进程ID;然后运行程序2,程序2的作用是接收到程序1中父进程的ID后,确认发送信息对象,然后每隔2秒钟发送一个SIGUSR1信号给程序1中的父进程。 程序运行用Ctrl+C结束。
1#include <stdio.h>
2#include <unistd.h>
3#include <signal.h>
4#include <stdbool.h>
5
6void handler(int signum)
7{
8 printf("接收到SIGUSR1\n");
9 return;
10}
11
12int main(void)
13{
14 printf("我的PID是%d\n", getpid());
15 signal(SIGUSR1, handler);
16
17 while (true)
18 ;
19
20 return 0;
21}
1#include <stdio.h>
2#include <stdlib.h>
3#include <signal.h>
4#include <unistd.h>
5#include <sys/types.h>
6
7#define ERR -1
8
9int main() {
10 pid_t pid;
11
12 printf("输入程序1的PID:");
13 scanf("%d", &pid);
14
15 while (1) {
16 if (kill(pid, SIGUSR1) == ERR) {
17 perror("发送信号失败\n");
18 return -1;
19 }
20 printf("发送成功\n");
21 sleep(2);
22 }
23
24 return 0;
25}
3、设计一个程序:要求主程序运行时,即使用户按下Ctrl+C键也不能影响正在运行的程序,即让信号处于阻塞状态;当主程序运行完毕后才进入自定义信号处理函数执行。要求: (1)主程序:每2秒钟输出提示“当前程序处于信号阻塞状态!”,循环显示5次 (2)自定义信号处理函数:查看当前路径下的所有文件信息。
1#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <signal.h>
5#include <dirent.h>
6#include <stdbool.h>
7#include <sys/types.h>
8
9#define ERR -1
10
11void handler(int signum)
12{
13 printf("接收到SIGINT\n");
14 execl("/bin/ls", "ls", "-l", NULL);
15 return;
16}
17
18int main(void)
19{
20 sigset_t set;
21 sigemptyset(&set);
22
23 sigaddset(&set, SIGINT);
24
25 if (sigprocmask(SIG_BLOCK, &set, NULL) == ERR)
26 {
27 printf("屏蔽SIGINT信号失败");
28 return -1;
29 }
30
31 signal(SIGINT, handler);
32
33 for (int i = 0; i < 5; i++)
34 {
35 printf("当前程序处于阻塞状态!\n");
36 sleep(2);
37 }
38
39 if (sigprocmask(SIG_UNBLOCK, &set, NULL) == ERR)
40 {
41 printf("解除信号屏蔽失败!\n");
42 return -1;
43 }
44 printf("解除信号屏蔽成功!\n");
45
46 while (true)
47 {
48 pause();
49 }
50
51 return 0;
52}