Trang 1 trên tổng số 2 12 Cuối cùngCuối cùng
Từ 1 tới 10 trên tổng số 15 kết quả

Đề tài: Xử lý 2 tiến trình bằng Message Queue trong lập trình C?

  1. #1
    Ngày gia nhập
    03 2009
    Bài viết
    203

    Mặc định Xử lý 2 tiến trình bằng Message Queue trong lập trình C?

    Mình đang làm một đồ án tìm hiểu cơ chế giao tiếp giữa 2 tiến trình dùng Message Queue nhưng thật sự chưa hiểu lắm. Đề tài là thế này:
    - Tạo ra 2 quá trình. Quá trình thứ nhất đọc file từ nhiểu chuỗi liên tiếp. Mỗi chuỗi gồm các phép toán +,-,*,/, và 2 toán hạng. Ví dụ:
    3+5
    4*2
    2-1
    6/3
    - Sau đó quá trình thứ nhất truyền dữ liệu này sang quá trình thứ 2. Quá trình thứ 2 thực hiện tính toán và trả chuỗi kết quả về lại cho quá trình thứ nhất để ghi lại file như sau:
    3+5=8
    4*2=8
    2-1=1
    6/3=2
    =>Dùng hàm fork() để tạo ra 2 quá trình
    Mong các bạn có thể giúp đỡ
    Mình cũng đã tìm hiểu một số code nhưng chưa hiểu và chưa thể chạy được. Vậy mong các bạn có thể xem qua và giúp mình.
    Xin cám ơn!

    Quá trình thứ nhất:
    file: tientrinh1.c
    Code:
    /*Chuong trinh tao va gui thong diep vao hang doi toan cuc cua he thong*/
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<sys/types.h>
    #include<sys/ipc.h>	    	/*cac ham SysV IPC*/
    #include<sys/msg.h>	    	/*cac ham xu ly thong diep*/
    #include"queue_defs.h"  	/*Su dung cac hang tu dinh nghia*/
    //tao cau truc thong diep
    struct msgbuf
    {
    	int mtype;
    	char mtext[MAX_SIZE];
    };
    //Chuong trinh chinh
    int main()
    {
    	int queue_id,len,num_mess;		//ID cua hang doi tao ra
    	struct msgbuf* msg;				//Cau truc chua noi dung thong diep
    	int i;							//so dem
    	int rc;							//Ma loi tra ve cua ham
    	char buffer[MAX_SIZE];			//bo dem chua ki tu nhap vao
    /*Tao hang doi chung co the truy xuat boi moi tien trinh*/
     	queue_id=msgget(QUEUE_ID,IPC_CREAT|0777);
    	if(queue_id==-1)
    	{
     		perror("main:msgget error");
     		exit(1);
     	}
     	printf("Thong diep hang doi duoc tao ra...,voi queue_id '%d'.\n",queue_id);
    	sleep(1);
    	printf("Nhap so chuoi thong diep can thuc hien:",num_mess);
    	scanf("%d",&num_mess);
    /*Nhap cac chuoi gom hai toan hang va mot toan tu*/
     	printf("Nhap %d chuoi cac phep toan can thuc hien:\n",num_mess);
    	for(i=0;i<=num_mess-1;i++)
    	{
    		scanf("%s",buffer);	//chep du lieu vao bo dem
    		(void) strcpy(msg->mtext,buffer);
     		msg->mtype= 1;		//Tao kieu thong diep bang 1
    		len=strlen(msg->mtext)+1;	
    /*Gui thong diep vao hang doi*/
    		rc=msgsnd(queue_id,msg,len,0);
    		if (rc==-1)
    		{
    	  		printf ("%d, %s, %d\n", queue_id,msg->mtype,len);
                    	perror("Co loi trong viec gui thong diep vao hang doi");        
                    	exit(1);
      		}
     }
     printf("Da khoi tao %d thong diep trong hang doi.\n",num_mess);
     return 0;
    }
    QUá trình thứ 2:
    file: tientrinh2.c
    Code:
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<unistd.h>		/*sleep()*/
    #include<sys/types.h>
    #include<sys/ipc.h>		/*cac ham SysV IPC*/
    #include<sys/msg.h>		/*cac ham xu ly thong diep*/
    #include"queue_defs.h"
    char dau[4][5]={"CONG", "TRU", "NHAN", "CHIA"};
    enum OPERATOR{CONG, TRU, NHAN, CHIA};
    /*khai bao cau truc thong diep*/
    struct msgbuf1
    {
    	long int mtype;
    	char mtext[MAX_SIZE];
    };
    //ham tinh ket qua tu hai toan hang va mot toan tu cho truoc
    int Tinh(int op, int a, int b){
    	switch(op){
    		case CONG: a+=b;break;
    		case TRU: a-=b;break;
    		case NHAN: a*=b;break;
    		case CHIA: a/=b;break;
    	}
    	return a;
    }
    void Ketqua(char s[])
    {
    	int a = 0, b = 0;
    	int operator = CONG;
    	char so;
    	int i;
    	int tam = 0;  
    	for(i=0; i<strlen(s); i++)
    	{
      		if((s[i]=='+')||(s[i]=='-')||(s[i]=='*')||(s[i]=='/'))
    		{	   
    	   		a = Tinh(operator, a, b);
    	   		switch(s[i])	// phep tinh tiep theo
    			{ 
    	   			case '+': operator = CONG;break;
    				case '-': operator = TRU;break;
    				case '*': operator = NHAN;break;
    				case '/': operator = CHIA;break;
    	   		}
    	  		b = 0;
    		}
    		else
    		{
    			so = s[i] - '0';
    			if((so>=0)&&(so<=9))
    				b=b*10+so;
    			else
    			{
    				printf("\nDay '%s' khong hop le", s);
    				return;
    			}
    		}
      	}
      	a = Tinh(operator, a, b);
      	printf("%s = %d\n", s, a);
    }
    /*chuong trinh chinh*/
    int main(int argc,char* argv[])
    {
    	int queue_id;			//ID cua hang doi thong diep
    	int msg_type;			//kieu thong diep can lay ra
    	int rc;					//luu ma loi tra ve cua ham
    	struct msgbuf1* msg;	//Bien cau truc luu noi noi thong diep
    	char* buffer;			//bo dem chua chuoi ki tu nhap vao
    /*lay ve dinh danh cua hang doi he thong can truy cap*/ 
    	msg_type=atoi(argv[1]);
    	if (msg_type!=1)
     	{
      		fprintf(stderr,"Su dung:%s <msg_type>\n",argv[0]);
      		fprintf(stderr,"	   <msg_type> phai la 1.\n");
      		exit(1); 
     	}
    	queue_id=msgget(QUEUE_ID,0);
    	if(queue_id==-1)
    	{
    		perror("main: msgget error");
    		exit(1);
    	} 
    	printf("Thong diep hang doi duoc mo, voi queue_id'%d'.\n",queue_id);
    /*Lap lan luot cac thong diep tu hang doi theo kieu thong diep chi dinh tu tham so dong lenh*/
    	printf("Ket qua nhan duoc:\n");
    	sleep(1);
    	do
    	{
    		rc=msgrcv(queue_id,msg,MAX_SIZE+1,msg_type,0);
    		if (rc==-1)
    		{
    			perror("main:msgrcv error");
    			exit(1);
    		}
    		Ketqua(msg->mtext);
    		sleep(1);
    	}while(1);
    return;
    }
    File include
    file: queue_defs.h
    Code:
    #ifndef QUEUE_DEF_H
    #define QUEUE_DEF_H
    //khoa dat cho hang doi
    #define QUEUE_ID 111
    //kich thuoc toi da cho hang doi
    #define MAX_SIZE 10
    #endif
    File mã nguồn (ko biết vì lỗi gì mà ko thể upload trực tiếp lên đây được): http://www.mediafire.com/?hbdhb7g1juas9eh

    sr: bài trước mình post nhầm nên mới sửa lại
    Ps:Mình đã chạy được 2 tiến trình trên. Nhưng chưa theo yêu cầu của bài toán. Yêu cầu là phải dùng hàm Fork. Vậy ai có thể thì giúp mình.Thank
    Đã được chỉnh sửa lần cuối bởi hvcuongit : 28-01-2015 lúc 01:59 PM.

  2. #2
    Ngày gia nhập
    10 2010
    Nơi ở
    hà nội
    Bài viết
    50

    bạn ơi làm sao để chạy hai chương trình trên thế ? cám ơi bạn trước nhé !
    mong được mọi người chỉ bảo
    duongquyet90@gmail.com
    http://duongquyet.forumvi.com

  3. #3
    Ngày gia nhập
    03 2009
    Bài viết
    203

    Trích dẫn Nguyên bản được gửi bởi duongquyet Xem bài viết
    bạn ơi làm sao để chạy hai chương trình trên thế ? cám ơi bạn trước nhé !
    Bạn chạy tientrinh1 sau đó tắt đi rồi tiếp tục chạy tientrinh2.

  4. #4
    Ngày gia nhập
    11 2010
    Nơi ở
    Black Hole
    Bài viết
    824

    Trước hết bạn phải hiểu về fork().

    Khi dùng fork() proccessus "con" sẽ thực hiện chương trình 1.
    processus "cha" sẽ chờ "con" làm xong rồi mới làm chương trình 2 với sự giúp đỡ của waitpid() trong sys/wait.h

    Ý tưởng là như vậy.
    Come as guest...... stay as family......... because we're smiling together.

  5. #5
    Ngày gia nhập
    01 2011
    Bài viết
    3

    Bạn ơi mình đang làm tiểu luận cái này.Mà chưa biết làm sao tiến trình 1 xử lí xong rùi làm sao nó gửi kết quả về lại tiến trình 2.Hic làm sao đây hic

  6. #6
    Ngày gia nhập
    11 2010
    Nơi ở
    Black Hole
    Bài viết
    824

    Mặc định Xử lý 2 tiến trình bằng Message Queue trong lập trình C?

    Cách đơn giản nhất là các biến chung của 2 tiến trình dc để vào file header và truy xuất ra ngoài bởi externe.
    Làm như vậy, giá trị của các biến chung sẽ dc nạp bởi quá trình 1 và sử dụng bởi quá trình 2 .

    Hoặc :

    Thô thiển hơn thì ghi hết kết quả quá trình 1 vào 1 file và sử dụng nó trong quá trình 2. Nhớ xóa file khi xong việc. Cách này dễ hiểu nhưng thô lắm.
    Come as guest...... stay as family......... because we're smiling together.

  7. #7
    Ngày gia nhập
    07 2006
    Nơi ở
    Hanoi, Vietnam
    Bài viết
    2,750

    Ngoài sử dụng hàm waitpid, bạn nên sử dụng cơ chế share memory để chia sẻ thông tin giữa các process.

    Mình có một ví dụ cho bạn đây:

    C Code:
    1. /*
    2. * A very simple server using Shared Memory example to communicate between processes.
    3. *
    4. * The parent will assign the shared memory segment to a random integer, and the child process will
    5. * display what it sees.
    6. */
    7.  
    8. //needed for the Shared Memory Functionality
    9. //#include <sys/ipc.h>
    10. #include <sys/shm.h>
    11.  
    12. //console based IO library
    13. #include <iostream>
    14.  
    15. //For generating our keys
    16. #include <cstdlib> //needed for the rand function
    17. #include <ctime> //needed to work with time for seeding
    18.  
    19. using namespace std;
    20.  
    21. //These are our function declarations
    22. void *get_shared_memory_segment(const int &, const char *); //getting shared memory segments
    23.  
    24. int main(int argc, char *argv[])
    25. {
    26.      //constants for shared memory sizes
    27.      const int SHM_INT_SIZE = sizeof(int);
    28.      const int MAX_CHILDREN = 7;
    29.  
    30.      //Message Count
    31.      int *shared_int, *child_count, pid;
    32.    
    33.      //We do not want any geeky stuff happening with the child processes later on, so set this up so that
    34.      //the parent does not need to wait for the child to terminate
    35.      signal(SIGCLD, SIG_IGN);
    36.    
    37.      //seed the random number generator
    38.      srand(time(0));
    39.    
    40.      //Be verbose, let the console know how large the shared memory segment is set to
    41.      cout << "Size of Shared Memory Segment for ints: " << SHM_INT_SIZE << endl;
    42.            
    43.      //get our shared memory segments
    44.      shared_int = (int *)get_shared_memory_segment(SHM_INT_SIZE, argv[0]);
    45.      child_count = (int *)get_shared_memory_segment(SHM_INT_SIZE, argv[0]);
    46.          
    47.      if ((!shared_int) || (!child_count))
    48.      {
    49.           cerr << "Error allocating shared memory!" << endl;
    50.           shared_int = NULL;
    51.           child_count = NULL;
    52.           exit(-1);
    53.      }
    54.    
    55.      //initialize our counts to 0
    56.      *shared_int = 0;
    57.      *child_count = 0;
    58.  
    59.      //Repeat indefinitly
    60.      while (1) {
    61.       if (*child_count < MAX_CHILDREN)
    62.       {
    63.           *child_count = *child_count + 1;
    64.           cout << "--------------------------------" << endl;
    65.           cout << "Number of Children after fork: " << *child_count << endl;
    66.           cout << "--------------------------------" << endl;
    67.            
    68.           pid = fork();
    69.        
    70.            if (pid < 0)
    71.            {
    72.                cerr << "Error on fork!" << endl;
    73.                 shared_int = NULL;
    74.                 child_count = NULL;
    75.                 exit(-1);    
    76.            }
    77.       }
    78.       else
    79.       {
    80.            cout << "--------------------------------" << endl;
    81.            cout << "Max children reached. I am not spawning anymore." << endl;
    82.            cout << "--------------------------------" << endl;
    83.       }
    84.       if (pid == 0)  {
    85.           //Inside of child process
    86.            
    87.           for (int x = 0; x < 20; x++)
    88.           {
    89.           cout << "I am a child " << getpid() << " and I see: " << *shared_int << endl;
    90.           sleep(3);
    91.           }
    92.            
    93.           *child_count = *child_count - 1;
    94.           cout << "--------------------------------" << endl;
    95.           cout << "I am dieing... Number of Childred: " << *child_count << endl;
    96.           cout << "--------------------------------" << endl;
    97.           //Exit child process
    98.           exit(0);
    99.          }
    100.          else
    101.       {
    102.           //Inside of parent process
    103.           *shared_int = rand();
    104.           cout << "I am the parent " << getpid() << " and I just set the shared memory segment to: " << *shared_int << endl;
    105.           sleep(5);
    106.       }
    107.      }
    108.    
    109.      return 0; /* we never get here due to CTRL-C the parent */
    110. }
    111.  
    112.  
    113. ///////////////////////////////////////////////////////////////////////////////////////
    114. //This will allocate the Shared Memory Segment and return a pointer to that segment
    115. void *get_shared_memory_segment(const int &size, const char *filename)
    116. {
    117.      //Variables for our Shared Memory Segment
    118.      key_t key;
    119.      int shmid;
    120.      int err = 0;
    121.  
    122.      //This is our local pointer to the shared memory segment
    123.      void *temp_shm_pointer;
    124.  
    125.      //Create our shared memory key for client connections
    126.      if ((key = ftok(filename, 1 + (rand() % 255) )) == -1)
    127.                 //error("Failed to FTOK");
    128.           err = 1;
    129.      
    130.      //Connect to the shared memory segment and get the shared memory ID
    131.      if ((shmid = shmget(key, size, IPC_CREAT | 0600)) == -1)
    132.      //error("shmget attempt failed");
    133.      err = 1;
    134.  
    135.      // point the clients to the segment
    136.      temp_shm_pointer = (void *)shmat(shmid, 0, 0);
    137.      if (temp_shm_pointer == (void *)(-1))
    138.         //error("shmat failure");
    139.      err = 1;
    140.  
    141.      //Return the pointer
    142.      if (!err)
    143.           return temp_shm_pointer;
    144.      else
    145.      return 0;
    146. }

    Ngoài ra bạn có thể sử dụng một cách rất đơn giản là: in kết quả tính toán của process1 lên màn hình và truyền nó cho process thứ 2 theo shell command như sau:

    process1 | process 2

    với process1 sẽ làm việc và in kết quả ra màn hình, còn process2 sẽ nhận tham số là kết quả process1 đã in ra màn hình.
    Email: admin[@]congdongcviet.com | CC to: info[@]congdongcviet.com
    Phone: 0972 89 7667 (Office: 04 6329 2380)
    Yahoo & Skype: dreaminess_world (Vui lòng chỉ rõ mục đích ngay khi liên hệ, cảm ơn!)

    Một người nào đó coi thường ý thức kỷ luật cũng có nghĩa là người đó đã coi thường tương lai số phận của chính bản thân người đó. Những người coi thường ý thức kỷ luật sẽ không bao giờ có được sự thành công trong sự nghiệp!

  8. #8
    Ngày gia nhập
    10 2010
    Bài viết
    20

    bạn ơi, mình cũng làm đề tài này nhưng dùng SHARED MEMORY, bạn có thể giúp mình chuyển qua dạng đó được ko?

  9. #9
    Ngày gia nhập
    11 2010
    Nơi ở
    Black Hole
    Bài viết
    824

    code của anh Kevin rõ ràng rồi mà. Phương pháp thì như trong code,nếu ko thì dùng tube "|" trong lunix cũng dc mà .
    Come as guest...... stay as family......... because we're smiling together.

  10. #10
    Ngày gia nhập
    01 2011
    Bài viết
    3

    Trích dẫn Nguyên bản được gửi bởi clamvn Xem bài viết
    Cách đơn giản nhất là các biến chung của 2 tiến trình dc để vào file header và truy xuất ra ngoài bởi externe.
    Làm như vậy, giá trị của các biến chung sẽ dc nạp bởi quá trình 1 và sử dụng bởi quá trình 2 .

    Hoặc :

    Thô thiển hơn thì ghi hết kết quả quá trình 1 vào 1 file và sử dụng nó trong quá trình 2. Nhớ xóa file khi xong việc. Cách này dễ hiểu nhưng thô lắm.
    K đc bạn ơi.hai tiến trình mình để trong 2 project khác nhau.tạo 2 file header dùng biến chung nhưng chỉ có ảnh hưởng trong mỗi tiến trình đi qua tiến trình kia trở lại gtri bằng gtri trong file header

Các đề tài tương tự

  1. Lập trình C dùng message queue để giao tiếp giữa 2 quá trình trong C?
    Gửi bởi tienhienpt trong diễn đàn Thắc mắc lập trình C/C++ trên Linux
    Trả lời: 5
    Bài viết cuối: 17-04-2011, 06:49 PM
  2. Lập trình C Thực hiện bài toán dùng message queue để giao tiếp giứa 2 quá trình.
    Gửi bởi haidag20101991 trong diễn đàn Thắc mắc lập trình C/C++ trên Linux
    Trả lời: 0
    Bài viết cuối: 12-04-2011, 01:27 PM
  3. MS SQL Lỗi Không gửi được message vào Queue trong sql server 2008
    Gửi bởi namtran1988 trong diễn đàn Thắc mắc Microsoft SQL Server & Microsoft Access
    Trả lời: 0
    Bài viết cuối: 24-03-2011, 09:12 AM
  4. Lập Trình đa nhiệm và giao tiếp giữa các thread thông qua message queue
    Gửi bởi Cpro trong diễn đàn Windows API, Hooking, xử lý Windows Message
    Trả lời: 1
    Bài viết cuối: 22-01-2009, 11:01 AM
  5. Lập Trình đa nhiệm và giao tiếp giữa các thread thông qua message queue
    Gửi bởi Cpro trong diễn đàn Thắc mắc lập trình Visual C++
    Trả lời: 1
    Bài viết cuối: 22-01-2009, 11:01 AM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn