The parent process of passing the first argument from argv [1] is an integer greater than 3 for the child process through Pipe.. The child process receives, calculates the factorial numb
Trang 1TRƯỜNG ĐẠI HỌC TÔN ĐỨC THẮNG KHOA CÔNG NGHỆ THÔNG TIN
BÁO CÁO BÀI TẬP NMHĐH
HK2, 2022-2023 Lab 6 Nhóm: 10 Tổ: 02
Trần Tuấn Kiệt – (MSSV: 52300040)
Trang 2Mục lục
……….
Trang 3A PHẦN THỰC HÀNH
I Unnamed pipe:
1 The parent process of passing the first argument from argv [1] is an integer greater than 3 for the child process through Pipe The child process receives, calculates the factorial number n! = 1*2*…* n and writes it to the pipe The parent process of receiving and exporting data to the screen.
A: Code Chương Trình
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int factorial(int n) {
int result = 1;
for (int i = 2; i <= n; i++) {
result *= i;
}
return result;
}
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <number>\n", argv[0]);
return EXIT_FAILURE;
}
int num = atoi(argv[1]);
Trang 4if (num <= 3) {
fprintf(stderr, "Number must be greater than 3\n"); return EXIT_FAILURE;
}
int pipefd[2];
if (pipe(pipefd) == -1) {
perror("pipe");
return EXIT_FAILURE;
}
pid_t pid = fork();
if (pid < 0) {
perror("fork");
return EXIT_FAILURE;
}
if (pid == 0) { // Tiến trình con
close(pipefd[0]);
int result = factorial(num);
if (write(pipefd[1], &result, sizeof(result)) == -1) { perror("write");
return EXIT_FAILURE;
}
Trang 5close(pipefd[1]);
exit(EXIT_SUCCESS);
} else { // Tiến trình cha
close(pipefd[1]);
int result;
if (read(pipefd[0], &result, sizeof(result)) == -1) { perror("read");
return EXIT_FAILURE;
}
close(pipefd[0]);
printf("Factorial of %d is: %d\n", num, result); }
return EXIT_SUCCESS;
}
B: Kết Quả Demo
Trang 62 The parent process reads two integers and one operation +, -, *, / and passes all to the child process The child process calculates the result and returns it to the parent process The parent process writes the result to a file.
A: Code Chương Trình
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main(int argc, char *argv[]) {
if (argc != 5) {
fprintf(stderr, "Usage: %s <num1> <num2> <operation> <output_filename>\ nNote that multiplication will be written as '*' to avoid the machine misinterpreting it
as another function\n", argv[0]);
return EXIT_FAILURE;
}
int num1 = atoi(argv[1]);
int num2 = atoi(argv[2]);
char op = argv[3][0];
char* output_filename = argv[4];
int pipefd[2];
pid_t pid;
if (pipe(pipefd) == -1) {
perror("pipe");
return EXIT_FAILURE;
}
pid = fork();
if (pid < 0) {
perror("fork");
return EXIT_FAILURE;
}
Trang 7if (pid == 0) { // Tiến trình con
close(pipefd[0]);
int result;
switch (op) {
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
case '*':
result = num1 * num2;
break;
case '/':
if (num2 != 0)
result = num1 / num2;
else {
fprintf(stderr, "Error: Division by zero\n"); close(pipefd[1]);
exit(EXIT_FAILURE);
}
break;
default:
fprintf(stderr, "Error: Invalid operation\n"); close(pipefd[1]);
exit(EXIT_FAILURE);
}
FILE *file = fopen(output_filename, "w");
if (file == NULL) {
perror("fopen");
close(pipefd[1]);
exit(EXIT_FAILURE);
}
Trang 8fprintf(file, "%d %c %d = %d\n", num1, op, num2, result); fclose(file);
close(pipefd[1]);
exit(EXIT_SUCCESS);
} else { // Tiến trình cha
close(pipefd[1]);
wait(NULL); // Đợi tiến trình con hoàn thành
printf("Result has been written to '%s'\n", output_filename); }
return EXIT_SUCCESS;
}
B: Kết Quả Demo
II Named pipe:
Slove 2 above problems with named pipe.
1.
A: Code Chương Trình
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
Trang 9int factorial(int n) {
if (n == 0)
return 1;
else
return n * factorial(n - 1);
}
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <number>\n", argv[0]); return 1;
}
int num = atoi(argv[1]);
if (num <= 3) {
fprintf(stderr, "Number must be greater than 3.\n"); return 1;
}
const char *fifo_name = "/tmp/factorial_pipe"; mkfifo(fifo_name, 0666);
pid_t pid = fork();
if (pid == -1) {
perror("fork");
return 1;
}
if (pid == 0) { // Child process
int fd = open(fifo_name, O_WRONLY);
if (fd == -1) {
perror("open");
return 1;
}
int result = factorial(num);
write(fd, &result, sizeof(result));
close(fd);
exit(0);
} else { // Parent process
int fd = open(fifo_name, O_RDONLY);
if (fd == -1) {
perror("open");
return 1;
Trang 10}
int result;
read(fd, &result, sizeof(result));
printf("Factorial of %d is: %d\n", num, result); close(fd);
wait(NULL);
}
unlink(fifo_name); // Remove the FIFO return 0;
}
B: Kết Quả Demo
2.
A: Code Chương Trình
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#define FIFO_FILE "/tmp/calculator_fifo"
int main() {
// Create named pipe
mkfifo(FIFO_FILE, 0666);
Trang 11pid_t pid = fork();
if (pid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (pid == 0) { // Child process // Open pipe for reading
int fd = open(FIFO_FILE, O_RDONLY);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
// Receive data from parent process int num1, num2;
char operation;
read(fd, &num1, sizeof(num1)); read(fd, &num2, sizeof(num2)); read(fd, &operation, sizeof(operation));
// Calculate result
int result;
switch (operation) {
case '+':
Trang 12result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
case '*':
result = num1 * num2;
break;
case '/':
if (num2 != 0)
result = num1 / num2;
else {
fprintf(stderr, "Error: Division by zero\n"); exit(EXIT_FAILURE);
}
break;
default:
fprintf(stderr, "Error: Invalid operation\n"); exit(EXIT_FAILURE);
}
// Close pipe
close(fd);
// Open pipe for writing
fd = open(FIFO_FILE, O_WRONLY);
Trang 13if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
// Send result back to parent process
write(fd, &result, sizeof(result));
// Close pipe
close(fd);
exit(EXIT_SUCCESS);
} else { // Parent process
// Open pipe for writing
int fd = open(FIFO_FILE, O_WRONLY);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
// Get input from user
int num1, num2;
char operation;
printf("Enter two integers and an operation (+, -, *, /): "); scanf("%d %d %c", &num1, &num2, &operation);
// Send data to child process
Trang 14write(fd, &num1, sizeof(num1)); write(fd, &num2, sizeof(num2)); write(fd, &operation, sizeof(operation));
// Close pipe
close(fd);
// Open pipe for reading
fd = open(FIFO_FILE, O_RDONLY);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
// Receive result from child process int result;
read(fd, &result, sizeof(result));
// Close pipe
close(fd);
// Write result to file
FILE *file = fopen("result.txt", "w");
if (file == NULL) {
perror("fopen");
exit(EXIT_FAILURE);
Trang 15}
fprintf(file, "Result: %d\n", result); fclose(file);
// Wait for child process to finish wait(NULL);
// Remove named pipe
unlink(FIFO_FILE);
}
return 0;
}
B: Kết Quả Demo
Trang 16KẾT LUẬN
Sau khi học và hoàn thành phần lab 6 nhóm thu được kết sau:
- Hiểu được cách sử dụng pipe
- Biết được cách giao tiếp giữa các tiến trình với nhau
- Thực hành và sử dụng được pipe
Chú ý bài làm giống nhau sẽ bị trừ điểm