Đang tải... (xem toàn văn)
PH N BÀI T PẦẬBài t p 1:ậTiến trình con chuyển đối số đầu tiên n từ argv [1], là một số nguyên lớn hơn 3,tới tiến trình cha của nó thông qua Hàng đợi Thông báo.. Tiến trình cha nhận,tính
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
Trang 3A PH N TH C HÀNHẦỰVí D 1:ụ
A: Code Chươ ng Trình// vd1.c
#include <stdio.h>#include <sys/types.h>#include <sys/ipc.h>int main(int argc, char* argv[]){
key_t key; char i;
for (i = 'a'; i < 'e'; i++) {
key = ftok(".", i);
printf("Proj = %c key = %d.\n", i, key); }
return 0;}
B: K t Qu Demoế ả
Ví D 2:ụ
A: Code Chươ ng Trình//vd2.c
#include <stdio.h>
Trang 4#include <unistd.h>#include <limits.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>#define MAX 5
int main(int argc, char* argv[]){
key = ftok(".", proj);
if (mid[i] = msgget(key, IPC_CREAT | 0666) == -1){
perror("Queue created\n");return 1;
fin = popen("ipcs", "r");
while ((n = read(fileno(fin), buffer, PIPE_BUF)) > 0){
write(fileno(stdout), buffer, n);}
Trang 5B: K t Qu Demoế ả
Ví D 3:ụ
A: Code Chươ ng Trình// vd3.c
#include <stdio.h>#include <unistd.h>#include <limits.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>#define MAX 5
int main(int argc, char* argv[]){
int mid; key_t key; struct msqid_ds buf; key = ftok(".", 'a');
if ((mid = msgget(key, IPC_CREAT | 0666)) == -1)
Trang 6{
perror("Queue create\n"); return 1;
}
msgctl(mid, IPC_STAT, &buf);
printf("MQ Permission structure information\n"); printf("Owner's user ID: %d\n", buf.msg_perm.uid); printf("Owner's group ID: %d\n", buf.msg_perm.gid); printf("Creator's user ID: %d\n", buf.msg_perm.cuid); printf("Creator's group ID: %d\n", buf.msg_perm.cgid); printf("Access mode in Hex: %04x\n", buf.msg_perm.mode); printf(" -\n"); printf("Additional selected MQ Structure information\n");
printf("Current number of byte in queue: %d\n", buf. msg_cbytes); printf("Current number of messages on queue: %d\n",
Trang 7Ví D 4:ụ
A: Code Chươ ng Trình// vd4.c
#include <stdio.h>#include <unistd.h>#include <limits.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>#include <string.h>#include <stdlib.h>struct Message{
int mtype; char* content;};
int main(int argc, char* argv[]){
int n, mid, id; key_t key; struct Message msg;
msg.content = (char*) malloc(BUFSIZ); if ((key = ftok(".", 'a')) == -1)
{
perror("key created\n"); return 1;
}
if ((mid = msgget(key, IPC_CREAT | 0666)) == -1) {
perror("Queue created\n"); return 2;
}
Trang 8switch(fork()) {
case -1:
perror("fork error\n"); return 3;
case 0:
msg.mtype = 10; msg.content = argv[1]; n = strlen(msg.content); printf("%s\n", msg.content); n += sizeof(msg.mtype);
if (msgsnd(mid, &msg, n, 0) == -1) {
perror("Message Send\n"); return 4;
} sleep(5);
printf("children receive from parent:\n"); if (n = msgrcv(mid, &msg, BUFSIZ, 11, 0) == -1) {
perror("Message Receive\n"); return 5;
}
msg.content[strlen(msg.content)] = 0; printf("%s\n", msg.content); return 0;
default: sleep(1);
if (n = msgrcv(mid, &msg, BUFSIZ, 10, 0) == -1) {
perror("Message Receive\n"); return 5;
}
printf("Parent receive from children: \n"); msg.content[strlen(msg.content)] = 0; printf("%s\n", msg.content);
printf(" -\n");
Trang 9printf("Message from parent\n"); msg.content = argv[2]; n = strlen(msg.content); msg.mtype = 11; n += sizeof(msg.mtype);
if (msgsnd(mid, &msg, n, 0) == -1) {
perror("Message receive\n"); return 4;
} sleep(10); return 0; }
return 0;}
B: K t Qu Demoế ả
B PH N BÀI T PẦẬBài t p 1:ậ
Tiến trình con chuyển đối số đầu tiên n từ argv [1], là một số nguyên lớn hơn 3,tới tiến trình cha của nó thông qua Hàng đợi Thông báo Tiến trình cha nhận,tính tổng giai thừa của các số từ 1 đến n và ghi nó vào Hàng đợi Thông báo Cáctiến trình con nhận và xuất dữ liệu ra màn hình.
A: Code Chươ ng Trình:// bai1.c
#include <stdio.h>#include <stdlib.h>
Trang 10#include <unistd.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>// Định nghĩa cấu trúc tin nhắnstruct message {
long mtype; // Loại tin nhắn int data; // Dữ liệu cần gửi};
int main(int argc, char *argv[]) { if (argc != 2) {
fprintf(stderr, "Sử dụng: %s <n>\n", argv[0]); exit(EXIT_FAILURE);
}
int n = atoi(argv[1]); // Tạo hàng đợi tin nhắn
key_t key = ftok("message_queue_key", 65); int msgid = msgget(key, 0666 | IPC_CREAT); // Tạo một tiến trình con
pid_t pid = fork(); if (pid < 0) {
perror("Fork thất bại"); exit(EXIT_FAILURE); }
if (pid == 0) { // Tiến trình con // Gửi giá trị của n đến tiến trình cha struct message msg;
msg.mtype = 1; // Loại tin nhắn phải lớn hơn 0 msg.data = n;
Trang 11msgsnd(msgid, &msg, sizeof(msg.data), 0); } else { // Tiến trình cha
// Nhận giá trị của n từ tiến trình con struct message msg;
msgrcv(msgid, &msg, sizeof(msg.data), 1, 0); // Tính tổng giai thừa và in kết quả
int sum = 0;
for (int i = 1; i <= msg.data; i++) { // Tính giai thừa cho mỗi số int factorial = 1;
for (int j = 1; j <= i; j++) { factorial *= j;
}
sum += factorial; }
printf("Tổng giai thừa từ 1 đến %d là %d\n", msg.data, sum); }
// Dọn dẹp: Xóa hàng đợi tin nhắn msgctl(msgid, IPC_RMID, NULL); return 0;
B: K t Qu Demo:ế ả
Trang 12Bài t p 2:ậ
Tiến trình con đọc dữ liệu từ một tệp gồm hai số nguyên và một phép toán +, -, *, / và chuyển tất cả cho tiến trình cha (bằng Hàng đợi Thông báo) Tiến trình cha tính toán kết quả và trả về cho tiến trình con Tiến trình con ghi kết quả vào tập tin.
A: Code Chươ ng Trình://bai2.c
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>struct message { long mtype; int num1; int num2; char operation; int result;};
int main() { int num1, num2; char operation;
// Nhập dữ liệu từ bàn phím
printf("Nhập hai số nguyên và một phép toán (+, -, *, /): "); scanf("%d %d %c", &num1, &num2, &operation); // Tạo hàng đợi tin nhắn
key_t key = ftok("message_queue_key", 65); int msgid = msgget(key, 0666 | IPC_CREAT); pid_t pid = fork();
Trang 13if (pid < 0) {
perror("Fork thất bại"); exit(EXIT_FAILURE); }
if (pid == 0) { // Tiến trình con struct message msg; msg.mtype = 1; msg.num1 = num1; msg.num2 = num2; msg.operation = operation;
msgsnd(msgid, &msg, sizeof(msg) - sizeof(long), 0); } else { // Tiến trình cha
Trang 14fprintf(stderr, "Lỗi: Phép toán không hợp lệ\n"); exit(EXIT_FAILURE);
B: K t Qu Demo:ế ả
Trang 15C K T LU NẾẬ
Sau khi học và hoàn thành phần lab 6 nhóm thu được kết sau:
1 Sử dụng Hàng Đợi Tin Nhắn (Message Queue): Trong cả hai bài toán, sửdụng hàng đợi tin nhắn giúp tạo ra một giao tiếp hiệu quả giữa các tiếntrình con và cha Hàng đợi tin nhắn là một cơ chế tốt để truyền thông tingiữa các tiến trình mà không cần phải chia sẻ bộ nhớ.
2 Xử lý Tiến Trình Con và Tiến Trình Cha: Quản lý tiến trình con và tiếntrình cha đòi hỏi sự hiểu biết vững về các hàm như fork() Sự hiểu biết nàyquan trọng để đảm bảo gửi và nhận thông tin một cách chính xác giữa cáctiến trình.
3 Điều Chỉnh Dữ Liệu: Cả hai bài toán đều thực hiện việc điều chỉnh dữ liệugiữa tiến trình con và cha Việc này đòi hỏi sự quản lý cẩn thận để tránhtình trạng đọc hoặc ghi đồng thời vào dữ liệu.
4 Kiểm soát lỗi và Xử lý Ngoại Lệ: Đảm bảo rằng chương trình của bạn cókiểm soát lỗi và xử lý ngoại lệ là quan trọng Trong các ví dụ trên, có cácđiểm kiểm tra lỗi để đảm bảo rằng các hoạt động như mở file, chia cho 0,và fork được thực hiện một cách an toàn.
5 Hiểu Biết Về Hệ Thống Tệp và Hệ Thống Tin Nhắn: Sự hiểu biết về cáchhệ thống tệp làm việc và cách hệ thống tin nhắn được triển khai trong môitrường Unix-like là quan trọng Điều này giúp bạn tối ưu hóa giao tiếp vàquản lý tệp tin.
6 Sự Hiểu Biết Về Thư Viện Thực Thi: Thêm -lrt: Việc thêm -lrt khi biêndịch là quan trọng để liên kết với thư viện rt để sử dụng các hàm liên quanđến hàng đợi tin nhắn.