【linux上机实验】实验八 Linux编程实验
1.使用系统调用对文件进行操作。
编写一个程序,把一个文件的内容复制到另一个文件上,即实现简单的copy功能。要求:只用open(),read(),write(),close()系统调用,程序要求带参数运行,第一个参数是源文件,第二个参数是目标文件。
步骤一:创建file_copy.c文件
vi file_copy.c
步骤二:将下列代码复制进步骤一创建的文件中并保存
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#define BUF_SIZE 1024
int main(int argc, char *argv[]) {
// 检查命令行参数是否正确
if (argc != 3) {
fprintf(stderr, "Usage: %s source_file target_file\n", argv[0]);
exit(EXIT_FAILURE);
}
int source_fd, target_fd;
ssize_t bytes_read, bytes_written;
char buffer[BUF_SIZE];
// 打开源文件,只读模式
source_fd = open(argv[1], O_RDONLY);
if (source_fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
// 创建或打开目标文件,可写模式
target_fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (target_fd == -1) {
perror("open");
close(source_fd);
exit(EXIT_FAILURE);
}
// 逐块读取源文件内容并写入目标文件
while ((bytes_read = read(source_fd, buffer, BUF_SIZE)) > 0) {
bytes_written = write(target_fd, buffer, bytes_read);
if (bytes_written != bytes_read) {
perror("write");
close(source_fd);
close(target_fd);
exit(EXIT_FAILURE);
}
}
if (bytes_read == -1) {
perror("read");
close(source_fd);
close(target_fd);
exit(EXIT_FAILURE);
}
// 关闭文件描述符
if (close(source_fd) == -1) {
perror("close");
exit(EXIT_FAILURE);
}
if (close(target_fd) == -1) {
perror("close");
exit(EXIT_FAILURE);
}
// 复制成功后显示提示消息
printf("文件复制成功!\n");
return 0;
}
步骤三:使用以下命令编译生成可执行文件:
gcc file_copy.c -o file_copy
步骤四:创建源文件
vi source_file
里面的内容自行写
步骤五:使用以下命令来运行程序进行文件内容的复制:
./file_copy source_file target_file (第一个参数source_file是源文件,第二个参数target_file是目标文件,第二个目标文件target_file命名可以随便改)
步骤六:查看目标文件里面的内容
2.使用系统调用对进程进行控制。
父进程首先用fork()创建一个子进程,若成功,再创建另一个子进程,之后3个进程并发运行。父进程调用wait(0)等待子进程结束,当两个子进程都结束时,父进程调用exit(0)终止自己。观察父子进程之间的同步过程。
步骤一:创建process_control.c文件
vi process_control.c
步骤二:将下列代码复制进步骤一创建的文件中并保存
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main() {
pid_t child1, child2;
int status;
// 创建第一个子进程
child1 = fork();
if (child1 == -1) {
perror("创建第一个子进程失败");
exit(EXIT_FAILURE);
} else if (child1 == 0) {
// 子进程1
printf("子进程1:%d,父进程:%d\n", getpid(), getppid());
sleep(2);
printf("子进程1:%d 结束\n", getpid());
exit(EXIT_SUCCESS);
}
// 创建第二个子进程
child2 = fork();
if (child2 == -1) {
perror("创建第二个子进程失败");
exit(EXIT_FAILURE);
} else if (child2 == 0) {
// 子进程2
printf("子进程2:%d,父进程:%d\n", getpid(), getppid());
sleep(3);
printf("子进程2:%d 结束\n", getpid());
exit(EXIT_SUCCESS);
}
// 等待子进程结束
waitpid(child1, &status, 0);
printf("子进程1:%d 已结束\n", child1);
waitpid(child2, &status, 0);
printf("子进程2:%d 已结束\n", child2);
// 父进程终止
printf("父进程:%d 结束\n", getpid());
exit(EXIT_SUCCESS);
}
步骤三:使用以下命令编译生成可执行文件:
gcc process_control.c -o process_control
步骤四:然后运行程序
./process_control
你将会观察到父进程创建了两个子进程,并等待子进程结束后再自己结束。
每个子进程打印出其进程ID和父进程ID,然后在一定时间后退出。父进程在子进程结束后打印出子进程ID,并最后退出自己。
注意,在运行程序时,你可能会注意到子进程的输出在父进程的输出之前或之后。这是由于线程间执行顺序的不确定性导致的,因此在不同的运行中可以看到不同的输出顺序。这是正常的行为。
3.使用管道机制进行进程通信。
使用无名管道pipe(),进行父子进程之间的通信。父进程先使用pipe()系统调用打开一个无名管道,之后创建一个子进程,为了正确通信,父进程关闭读通道,子进程关闭写通道。父进程向管道写一句话,子进程从管道读出这句话。完成一次通信后,父子进程分别关闭自己的读写通道,管道文件消失。
步骤一:创建pipe_example.c文件
vi pipe_example.c
步骤二:将下列代码复制进步骤一创建的文件中并保存
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
int fd[2];
pid_t pid;
char buffer[100];
if (pipe(fd) < 0) {
perror("pipe");
exit(EXIT_FAILURE);
}
pid = fork();
if (pid < 0) {
perror("fork");
exit(EXIT_FAILURE);
} else if (pid > 0) {
close(fd[0]);
printf("父进程写入管道。\n");
write(fd[1], "你好,子进程!", 22);
close(fd[1]);
} else {
close(fd[1]);
printf("子进程从管道中读取数据。\n");
read(fd[0], buffer, sizeof(buffer));
printf("子进程读:%s\n", buffer);
close(fd[0]);
}
return 0;
}
步骤三:使用以下命令编译生成可执行文件:
gcc pipe_example.c -o pipe_example
步骤四:然后运行程序
./pipe_example
完结,撒花!!!
本文来自博客园,作者:Cloudservice,转载请注明原文链接:https://www.cnblogs.com/whwh/p/17876513.html,只要学不死,就往死里学!