PHẦN BÀI TẬPBÀI 1: The child process passes the first argument n from argv [1], which is an integer greater than 3,to its parent process through the Message Queue.. The parent process re
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 7
Nhóm: 10 Tổ: 01
1: Trần Ngọc Hải My ( MSSV: 52300128)
Trang 2B PHẦN BÀI TẬP BÀI 1:
The child process passes the first argument n from argv [1], which is an integer greater than 3,
to its parent process through the Message Queue The parent process receive, calculates the sum of factorial of numbers from 1 to n and writes it to the Message Queue Child processes receive and output data to the screen
A: Code Chương Trình:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#define MAX_SIZE 256
struct message {
long mtype;
int data;
};
int factorial(int num) {
if (num == 0 || num == 1)
return 1;
else
Trang 3return num * factorial(num - 1);
}
int main(int argc, char *argv[]) {
if (argc < 2) {
fprintf(stderr, "Usage: %s <n> (where n > 3)\n", argv[0]); return EXIT_FAILURE;
}
int n = atoi(argv[1]);
if (n <= 3) {
fprintf(stderr, "n must be greater than 3\n");
return EXIT_FAILURE;
}
key_t key = ftok(".", 'm');
if (key == -1) {
perror("ftok");
return EXIT_FAILURE;
}
int msgid = msgget(key, 0666 | IPC_CREAT);
if (msgid == -1) {
perror("msgget");
return EXIT_FAILURE;
Trang 4}
pid_t pid = fork();
if (pid == -1) {
perror("fork");
return EXIT_FAILURE;
}
if (pid == 0) {
struct message msg_to_send;
msg_to_send.mtype = 1;
msg_to_send.data = n;
if (msgsnd(msgid, &msg_to_send, sizeof(int), 0) == -1) { perror("msgsnd");
return EXIT_FAILURE;
}
} else {
struct message msg_received;
if (msgrcv(msgid, &msg_received, sizeof(int), 1, 0) == -1) { perror("msgrcv");
return EXIT_FAILURE;
}
Trang 5int received_n = msg_received.data;
int sum_of_factorials = 0;
for (int i = 1; i <= received_n; i++) {
sum_of_factorials += factorial(i);
}
struct message msg_to_send;
msg_to_send.mtype = 1;
msg_to_send.data = sum_of_factorials;
if (msgsnd(msgid, &msg_to_send, sizeof(int), 0) == -1) { perror("msgsnd");
return EXIT_FAILURE;
}
}
if (pid == 0) {
struct message msg_received;
if (msgrcv(msgid, &msg_received, sizeof(int), 1, 0) == -1) { perror("msgrcv");
return EXIT_FAILURE;
}
Trang 6printf("Sum of factorials from 1 to %d is: %d\n", n, msg_received.data); }
if (pid != 0) {
if (msgctl(msgid, IPC_RMID, NULL) == -1) {
perror("msgctl");
return EXIT_FAILURE;
}
}
return EXIT_SUCCESS;
}
B: Kết Quả Demo:
BÀI 2:
The child process reads data from a file consisting of two integers and an operation +, -, *, / and passes all to the parent process (by a Message Queue) The parent process calculates the result and returns it to the child process The child process writes the result to the file
A: Code Chương Trình:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
Trang 7#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <sys/wait.h>
struct message {
long mtype;
int num1;
int num2;
char op;
};
void child_process(char *input_filename, char *output_filename) { FILE *input_file = fopen(input_filename, "r");
if (input_file == NULL) {
perror("Error opening input file");
exit(EXIT_FAILURE);
}
int num1, num2;
char op;
if (fscanf(input_file, "%d %d %c", &num1, &num2, &op) != 3) { perror("Error reading input file");
fclose(input_file);
exit(EXIT_FAILURE);
Trang 8}
fclose(input_file);
key_t key = ftok(".", 'm');
if (key == -1) {
perror("Error generating key for message queue");
exit(EXIT_FAILURE);
}
int msgqid = msgget(key, 0666 | IPC_CREAT);
if (msgqid == -1) {
perror("Error creating message queue");
exit(EXIT_FAILURE);
}
struct message msg;
msg.mtype = 1;
msg.num1 = num1;
msg.num2 = num2;
msg.op = op;
if (msgsnd(msgqid, &msg, sizeof(struct message) - sizeof(long), 0) == -1) { perror("Error sending message to parent process");
exit(EXIT_FAILURE);
}
Trang 9if (msgrcv(msgqid, &msg, sizeof(struct message) - sizeof(long), 2, 0) == -1) { perror("Error receiving message from parent process");
exit(EXIT_FAILURE);
}
FILE *output_file = fopen(output_filename, "w");
if (output_file == NULL) {
perror("Error opening output file");
exit(EXIT_FAILURE);
}
fprintf(output_file, "%d\n", msg.num1);
fclose(output_file);
if (msgctl(msgqid, IPC_RMID, NULL) == -1) {
perror("Error removing message queue");
exit(EXIT_FAILURE);
}
}
void parent_process() {
key_t key = ftok(".", 'm');
if (key == -1) {
perror("Error generating key for message queue");
Trang 10exit(EXIT_FAILURE);
}
int msgqid = msgget(key, 0666 | IPC_CREAT);
if (msgqid == -1) {
perror("Error creating message queue");
exit(EXIT_FAILURE);
}
struct message msg;
if (msgrcv(msgqid, &msg, sizeof(struct message) - sizeof(long), 1, 0) == -1) { perror("Error receiving message from child process");
exit(EXIT_FAILURE);
}
int result;
switch (msg.op) {
case '+':
result = msg.num1 + msg.num2;
break;
case '-':
result = msg.num1 - msg.num2;
break;
case '*':
result = msg.num1 * msg.num2;
Trang 11break;
case '/':
if (msg.num2 == 0) {
perror("Error: Division by zero");
exit(EXIT_FAILURE);
}
result = msg.num1 / msg.num2;
break;
default:
perror("Error: Invalid operation");
exit(EXIT_FAILURE);
}
msg.mtype = 2;
msg.num1 = result;
if (msgsnd(msgqid, &msg, sizeof(struct message) - sizeof(long), 0) == -1) { perror("Error sending result message to child process");
exit(EXIT_FAILURE);
}
}
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s <input_file> <output_file>\n", argv[0]);
Trang 12exit(EXIT_FAILURE);
}
pid_t pid = fork();
if (pid < 0) {
perror("Fork failed");
exit(EXIT_FAILURE);
} else if (pid == 0) {
child_process(argv[1], argv[2]);
exit(EXIT_SUCCESS);
} else {
parent_process();
int status;
wait(&status);
exit(EXIT_SUCCESS);
}
return 0;
}
B: Kết Quả Demo: