Liên lạc giữa hai tiến trình sử dụng Pipe

Pipe là một tiện ích được hỗ trợ trong hầu hết các ngôn ngữ lập trình vận hành trên các hệ thống đa nhiệm. Pipe cho phép hai quá trình nằm trên cùng một máy có thể trao đổi dữ liệu với nhau.

Dữ liệu đi trên Pipe theo một chiều nhất định. Khi sử dụng Pipe, người ta dùng một đầu cho việc viết dữ liệu vào và một đầu còn lại cho việc đọc dữ liệu ra.

 

doc9 trang | Chia sẻ: luyenbuizn | Lượt xem: 1163 | Lượt tải: 1download
Nội dung tài liệu Liên lạc giữa hai tiến trình sử dụng Pipe, để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
TRƯỜNG ĐẠI HỌC CÔNG NGHIỆP TP.HỒ CHÍ MINH KHOA CÔNG NGHỆ THÔNG TIN & TIỂU LUẬN MÔN HỆ ĐIỀU HÀNH Đề tài: Liên lạc giữa hai tiến trình sử dụng Pipe (Đề tài 5.2) Giảng viên hướng dẫn : Nguyễn Thành Thái Nhóm sv thực hiện : Nhóm 21 Sinh viên thực hiện : Lê Thanh Toàn Phạm Quốc Nguyên Đường Anh Tuấn TP.Hồ Chí Minh, tháng 4 năm 2011 ĐỀ TÀI Tạo ra 2 quá trình. Quá trình thứ nhất đọc từ file nhiều chuỗi liên tiếp, mỗi chuỗi gồm các phép toán +, -, *, / và hai toán hạng. Ví dụ trong file sẽ lưu các chuỗi dạng như sau : 2 + 3 1 - 2 4 * 6 15 / 3 Sau đó quá trình thứ nhất truyền các chuỗi dữ liệu này cho quá trình thứ hai. Quá trình thứ hai thực hiện tính toán và trả chuỗi kết quả về lại cho quá trình đầu tiên để ghi lại vào file như sau: 2 + 3 = 5 1 - 2 = -1 4 * 6 = 24 15 / 3 = 5 HƯỚNG GIẢI QUYẾT BÀI TOÁN Sử dụng kênh liên lạc Pipe để giao tiếp giữa hai tiến trình Sử dụng ngôn ngữ C để mô phỏng bài toán Sử dụng kênh liên lạc Pipe (ống dẫn) để giao tiếp giữa hai tiến trình: Pipe là một tiện ích được hỗ trợ trong hầu hết các ngôn ngữ lập trình vận hành trên các hệ thống đa nhiệm. Pipe cho phép hai quá trình nằm trên cùng một máy có thể trao đổi dữ liệu với nhau. Dữ liệu đi trên Pipe theo một chiều nhất định. Khi sử dụng Pipe, người ta dùng một đầu cho việc viết dữ liệu vào và một đầu còn lại cho việc đọc dữ liệu ra. Pipe thích hợp cho trường hợp dữ liệu tạo ra của quá trình này sẽ là dữ liệu đầu vào cho quá trình kia. Tuy nhiên ta cũng có thể sử dụng Pipe để xây dựng các ứng dụng theo kiến trúc Client- Server bằng cách sử dụng hai Pipe: một Pipe để truyền các yêu cầu (request), một Pipe để truyền các trả lời (reply). Có hai loại Pipe: Normal Pipe (Ống dẫn bình thường): Giới hạn trong phạm vi không gian địa chỉ của một quá trình mà thôi. Nó chỉ cho phép giao tiếp giữa quá trình cha với các quá trình con hay giữa các quá trình con của một quá trình với nhau. Java hỗ trợ Pipe loại này. Trong đó các quá trình con được thay thế bởi các luồng. Named Pipe (Ống dẫn có tên): Loại này có thể cho phép hai quá trình có không gian địa chỉ khác nhau (trên cùng một máy) giao tiếp với nhau. Thực chất nó giống như một tập tin với qui định rằng dữ liệu sẽ được lấy ra ở đầu tập tin và được thêm vào ở cuối tập tin. Thuật toán xử lý sử dụng ngôn ngữ C: Do trong môi trường Linux đã hỗ trợ sẵn kiểu Pipe cũng như tạo ra đa tiến trình nên ta sử dụng để lập trình một cách đơn giản hơn trong WINDOWS. Tạo một Pipe: rc=pipe(chatoicon); Hàm trên đã tạo ra 1 pipe theo tên là chatoicon. Nhưng không phải lúc nào cũng tạo ra thành công 1 pipe mà nó có thể xảy ra các trường hợp như sau. 1: Nếu rc= -1: Lỗi không tạo được pipe 2: Nếu rc= 0: tạo được pipe đọc 3: Nếu rc= 0: tạo được pipe ghi Khi đã tạo được pipe ta cần phải tạo ra được 2 tiến trình hoạt động với nhau một cách song song và dùng pipe ta vừa tạo được để giao tiếp giữa 2 tiến trình này. Để tạo được 2 tiến trình ta cần : pic=fork(); Do trong Linux đã hỗ trợ sẵn đa tiến trình nên ta chỉ cần gọi hàm fork() để tạo ra 2 tiến trình hoạt động một cách song song. Cũng như tạo pipe không phải lúc nào ta cũng tạo được thành công 2 tiến trình mà nó sẽ xảy ra các trường hợp sau: 1: Nếu pic = -1 : Lỗi không tạo được tiến trình 2: Nếu pic khác -1 ta tạo được 2 tiến trình hoạt động một cách song song. PHÂN TÍCH CODE CỦA BÀI TOÁN Code xử lý tiến trình 1: Tiến trình 1 đọc file và gửi cho tiến trình 2 xử lý. Sau khi nhận lại kết quả từ tiến trình 2 thì tiến hành ghi lại vào file. Đọc File Text và ghi vào dữ liệu đọc được vào trong pipe while((ch=fgetc(f))!=EOF) //Ghi trong khi chua gap ky tu ket thuc file { rc= write(pipe_ra[1],&ch,1); if(rc==-1) { perror("pipe loi ghi"); //Thong bao loi ghi close(pipe_vao[0]); close(pipe_ra[1]); exit(1); } } Ghi lại kết quả nhận được từ tiến trình 2 vào file text f1=fopen("hieu.txt","a");//Mo file de ghi ket qua rc=read(pipe_vao[0],str,sizeof(str)); if(rc<=0) { perror("doc va da ghi vao file");//Thong bao loi doc perror("\n"); close(pipe_vao[0]); close(pipe_ra[1]); exit(1); } fputs(str,f1); fflush(f1); } Code xử lý tiến trình 2: Tiến trình này lấy dữ liệu mà tiến trình 1 gửi vào pipe và xử lý các phép toán trên đó. Sau khi xử lý xong tiến trình 2 sẽ gửi lại kết quả cho tiến trình 1 vào pipe để tiến trình 1 thực hiện ghi lại vào file. Tiến trình 2 nhận dữ liệu từ pipe được gửi từ tiến trình 1. while ((read(pipe_vao[0],&ch,1)!=EOF)&&(ki!=(2*kt))) { //khối lệnh thực hiện xử lý dữ liệu } Tiến trình 2 xử lý dữ liệu nhận được. Thuật toán xử lý. Xử lý trên từng dòng. Tiến trình 1 đọc file đưa vào pipe là các ký tự liên tiếp.Vì vậy thuật toán chủ yếu là xử lý các phép tính trên các ký tự nhận được. Duyệt từng phần tử của pipe. Nếu không phải kí tự xuống dòng. Kiểm tra xem kí tự đó có phải là các phép toán +,-,*,/ hay không? Nếu không phải các phép toán thực hiện chuyển đổi ký tự đó về số và lưu vào mảng. Nếu là kí tự yêu cầu thực hiện các phép toán. Thực hiện phép toán vào lưu kết quả vào 1 mảng Nếu là ký tự xuống dòng: Thực hiện lại bước trên với dòng mới. Ghi mảng kết quả vào pipe để tiến trình 1 thực hiện lưu lại kết quả vào file text. Chi tiết thuật toán Thuật toán kiểm tra nếu không phải là phép tính thì đưa vào 1 mảng if((ch!='+')&&(ch!='-')&&(ch!='*')&&(ch!='/')) { strcpy(str," "); a[i] = double (ch); a[i] = (a[i] - 48); gcvt(a[i],4,str); i++; n=i; } else { strcpy(str," "); gan = ch; strcpy(str,&gan); m[k]=xuly(i); i=0; k++; } } Thuật toán Xử Lý các phép tính else //Neu gap ky tu sang dong { ki++; kq=0; strcpy(str,"="); strcpy(str1," "); m[k]=xuly(i); switch(gan) { case '+': { strcpy(str,"="); kq+=m[k-1]+m[k]; gcvt(kq,5,str1); strcat(str,str1); strcat(str,"\n"); break; } case '-': { strcpy(str,"="); kq=m[k-1]-m[k]; gcvt(kq,5,str1); strcat(str,str1); strcat(str,"\n"); break; } case '*': { strcpy(str,"="); kq=m[k-1]*m[k]; gcvt(kq,5,str1); strcat(str,str1); strcat(str,"\n"); break; } case '/' : { strcpy(str,"="); if(m[k]!=0) { kq=m[k-1]/m[k]; gcvt(kq,5,str1); strcat(str,str1); strcat(str,"\n"); } else { strcat(str,"Khong thuc hien duoc"); strcat(str,"\n"); } break; } } k=0; i=0; } Ghi lại kết quả vào pipe rc = write(pipe_ra[1],str,sizeof(str)); //Tien trinh con doc cac xau ket qua vao duong ong if (rc==-1) { perror("Ghi Ket Qua"); close(pipe_vao[0]); close(pipe_ra[1]); exit(1); } } KẾT LUẬN Chương trình mô phỏng bài toán liên lạc giữa hai tiến trình sử dụng kênh liên lạc Pipe chạy ổn định, đúng yêu cầu bài toán đặt ra.

Các file đính kèm theo tài liệu này:

  • docTieu luan He Dieu Hanh.doc