Thread: How to communicate between two processes

  1. #1
    Registered User
    Join Date
    Sep 2011
    Posts
    23

    How to communicate between two processes

    Hi everyone. I am new to Cboard. This is my first post.
    I am practicing Linux Programming. I am doing an Addressbook program in C using IPC. This program does Insert, Display, Delete and Modify.
    My task is to create two applications.
    All the selections for insert, delete, modify & delete will be done in application1.
    For Insertion:
    application1 has to take the input data(like name, address & phone#) and send them to application2. Application2 must receive the data and save them to a file.
    For Deletion: Application2 must be doing the deletion part
    For Display: Application2 sends data stored in file to Application1 for displaying them
    For Modify: Application2 does the modification part.

    I am using System() to create a new process and using Shared memory for IPC.

    I am successful in sending the data to second process and saving them to a file. I can also display the contents in the file. Can anyone please help in how to delete and modify the data.
    This is my code what i have done upto now. Thanks in Advance.

    address.c
    Code:
    #include<stdio.h>
    #include <sys/shm.h>
    #include <sys/stat.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <errno.h>
    
    typedef struct 
    {
      int select;
      char lastname[25];
      char firstname[25];
      char address[25];
      char phonenumber[25];
    }addressbook;
    
    #define SIZE 3
    addressbook a[SIZE]={0,0};
    
    void insert(void);
    void display(void);
    void delete(void);
    void modify(void);
    char *shared_memory;
    int i;
    
    int main()
    {
      int select;
      int segment_id;
      //char* shared_memory;
      int segment_size;
      key_t shm_key;
      const int shared_segment_size = 0x6500;
      shm_key = ftok("/home/madan/programs/shm_tok",'X');
      if(shm_key < 0) 
      {
        printf("failed to create the key %s\n",strerror(errno));
      }
      /* Allocate a shared memory segment. */
      segment_id = shmget (shm_key, shared_segment_size, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR);
      if(segment_id < 0) 
       {
         printf("error geting the segment id %s\n",strerror(errno));
       }
        printf("segment ID:%d\n", segment_id);
       /* Attach the shared memory segment. */
       shared_memory = (char*) shmat (segment_id, 0, 0);
       printf ("shared memory attached at address %p\n", shared_memory);
      do 
      {
      printf("Address book: \n Press\n 1: Insert \n 2: Display \n 3: Delete \n 4: Modify\n Enter:");
      scanf("%d", &select);
      switch(select)
      {
        case 1:
          insert();
          break;
        case 2:
          display();
          break;
        case 3:
          delete();
          break;
        case 4:
         modify();
          break;  
        default:
          printf("wrong selection\n");
          break;
      
      }
      if((select > 4) || (select < 1))
        break;
      }while(1);
          /* Detach the shared memory segment. */
       shmdt (shared_memory);
       /* Deallocate the shared memory segment.*/
       shmctl (segment_id, IPC_RMID, 0);  
      return 0;
    }
    
    void insert()
    {  
       
       for(i=0; i<SIZE; i++)
       {
        a[i].select=1;
        printf("enter details\n");
        printf("enter lastname of person %d:\n", i);
        scanf("%s", a[i].lastname);
        printf("enter firstname of person %d:\n", i);
        scanf("%s", a[i].firstname);
        printf("enter address of person %d:\n", i);
        scanf("%s", a[i].address);
        printf("enter phone number of person %d:\n", i);
        scanf("%s", a[i].phonenumber);
        memcpy(shared_memory, &a[i], sizeof(addressbook));
        system("./address-insert");
       }
    }
    
    void display()
    {
     //for(i=0; i<SIZE; i++)
     // {
       a[i].select=2;
     // printf("enter last name of the person to display the details:\n");
    //  scanf("%s", a[i].lastname);
      memcpy(shared_memory, &a, sizeof(addressbook));
      system("./address-insert");
      memcpy(&a, shared_memory, sizeof(addressbook));
      for(i=0; i<SIZE; i++)
      {
      printf("lastname of person %d: %s\n", i,a[i].lastname);
      printf("firstname of person %d: %s\n", i, a[i].firstname);
      printf("address of person %d: %s\n", i, a[i].address);
      printf("phone number of person %d: %s\n", i, a[i].phonenumber);
      }
      
    }
    
    void delete()
    {
      a[i].select=3;
      memcpy(shared_memory, &a, sizeof(addressbook));
      system("./address-insert");
    }
    
    void modify()
    {
      a[i].select=4;
        memcpy(shared_memory, &a, sizeof(addressbook));
      system("./address-insert");
    }
    -------------------------------------------------------------------------------------------------------------------------------------
    address-insert.c
    Code:
    #include <arpa/inet.h>
    #include <stdio.h>
    #include <sys/shm.h>
    #include <sys/stat.h>
    #include <string.h>
    #include <errno.h>
    
    typedef struct 
    {
      int select;
      char lastname[25];
      char firstname[25];
      char address[25];
      char phonenumber[25];
    } addressbook;
    #define SIZE 3
    addressbook a[SIZE]={0,0};
    
    void insert(void);
    void display(void);
    void delete(void);
    void modify(void);
    char* shared_memory;
     FILE *fp;
     int i;
     char *name;
    int main ()
    {
      int segment_id;
      
      
      
      int segment_size;
      key_t shm_key;
      shm_key = ftok("/home/madan/programs/shm_tok",'X');
      const int shared_segment_size = 0x6500;
      /* Allocate a shared memory segment. */
      segment_id = shmget (shm_key, shared_segment_size, S_IRUSR | S_IWUSR);
      
      if(segment_id < 0) 
      {
        printf("error:[%s]",strerror(errno));
      }
      printf("segment id %d\n",segment_id);
      /* Attach the shared memory segment. */
      shared_memory = (char*) shmat (segment_id, 0, 0);
      if(shared_memory == NULL)
      {
        printf("failed to attach the shared memory %s",strerror(errno));
      }
      printf ("shared memory2 attached at address %p\n", shared_memory);
      
      memcpy(&a[i], shared_memory, sizeof(addressbook));
      printf("select=%d\n", a[i].select);
      
     switch(a[i].select)
      {
        case 1:
          insert();
          break;
        case 2:
          display();
          break;
        case 3:
          delete();
          break;
        case 4:
          modify();
          break;
        default:
          printf("wrong selection\n");
          break;
      }
       /* Detach the shared memory segment. */
      shmdt (shared_memory);
      return 0;
    }
    
      void insert()
      {
       /* To insert data*/  
         fp = fopen("addressbook.dat","a+");
         fwrite(&a[i], sizeof(addressbook), 1, fp);
         fclose(fp);
      }
      
      void display()
      {
        /* To delete data */ 
        fp = fopen("addressbook.dat", "r");
        for(i=0; i<SIZE; i++)
        {
          fread(&a, sizeof(addressbook), 1, fp); 
          //memcpy(shared_memory, &a, sizeof(addressbook));
        }
      fclose(fp);
      }
      
      void delete()
      {
      /*To display data */
      printf("enter last name of the person to delete:\n");
      scanf("%s", name);
      printf("contact to be deleted is: %s", name);
      fp = fopen("addressbook.dat", "a+");
      for(i=0; i<SIZE; i++)
      {
        fread(&a[i], sizeof(addressbook), 1, fp);
        if(a[i].lastname == name)
        {
          printf("found\n");
        }
        else
          printf("not found\n");
      }
      fclose(fp);
      
      //memcpy(shared_memory, &a, sizeof(addressbook));
      
      }
      
      void modify()
      {
      /*To modify data */
      printf("enter last name of the person to modify the details:\n");
      scanf("%s", a[i].lastname);
      memcpy(shared_memory, &a, sizeof(addressbook));
      
      }
    The program is running with no errors. insert() and display() are working. Can someone help me the best way to send select variable to second application and how to do delete and modify part.
    Thanks in advance.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Surely at some point you learned to use strcmp instead of == when dealing with strings?

  3. #3
    Registered User
    Join Date
    Sep 2011
    Posts
    23
    yeah it make sense. thank you @tabstop.
    Can anyone please tell me how to pass the select option along with data to the second application. I am getting something wrong in passing the select option to application2.

  4. #4
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Global Variables Are Bad


    It would help immensely if you made all global variables local, unless absolutely necessary.

    address.c
    Code:
    void delete()
    {
        a[i].select = 3;
        memcpy(shared_memory, &a, sizeof(addressbook));
    God only knows what value i has when you get here. Suffice to say it's probably not 0. You are setting a[?].select to 3, but writing a[0] to shared memory. Note that, if you do insert first, you leave i == SIZE when you're done, so i is 3, and you do a[i].select, or a[3].select. But 3 is not a valid index for your array, you only have 0, 1, and 2 (0 to SIZE-1).

    address-insert.c
    Code:
    int i;
    Global variables are initialized to zero. Every time you start address-insert, i is zero. If i has to be synchronized between address and address-insert, you need to make sure that you write it to and read it from the shared memory too.

    You need to actually delete the entry from the file, or mark it as invalid at least. Also, you need to re-read the addressbook after you return from your system() call for delete or modify, since the contents may have changed.
    Last edited by anduril462; 09-02-2011 at 11:33 PM.

  5. #5
    Registered User
    Join Date
    Sep 2011
    Posts
    23
    @anduril462 thank you. it was a blunder i made (a[i].select=3). yes, variable 'i' has to be synchronized between two applications.
    yes what you said was correct, after delete and modify it must re-read the addressbook.

  6. #6
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    You should definitely avoid using 'i' as a global variable, since it's such a commonly used variable for loops, etc. Call it something descriptive and possibly prefix it with a 'g' to signify global, e.g. g_address_entry_number. Use a local 'i' in your functions where you need loop processing. Make as many things local as possible. Technically, you can even move your array and address_entry_number into main too, and pass them to the functions as necessary (you can do this in both programs).

  7. #7
    Registered User
    Join Date
    Sep 2011
    Posts
    23
    @anduril462 yeah sure i will make changes.
    Can we use use linked lists in this program, so that it will be easy to modify and delete contacts from the file. Please anyone suggest me how to use linked lists for this program.

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I thought you wanted to save these to a file as you go. Does this mean you want the whole addressbook in memory at one time, and only writing to a file at the end of the day? (Linked lists and flat database-like files don't work well together, necessarily.)

    If you do want a linked list, then you modify your struct to contain a link to the next struct.

  9. #9
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by chaituchemico View Post
    I am practicing Linux Programming. I am doing an Addressbook program in C using IPC. This program does Insert, Display, Delete and Modify.
    My task is to create two applications.
    All the selections for insert, delete, modify & delete will be done in application1.
    For Insertion:
    application1 has to take the input data(like name, address & phone#) and send them to application2. Application2 must receive the data and save them to a file.
    For Deletion: Application2 must be doing the deletion part
    For Display: Application2 sends data stored in file to Application1 for displaying them
    For Modify: Application2 does the modification part.
    It seems to me this is a straightforward client-server model, application 1 being the client (a user interface) and application 2 being a database server.

    IMO shared memory is not the best choice for facilitating that relationship; I think it is unnecessary and will tempt you into superfluously duplicating data when all you really need to do is transfer messages back and forth.

    If shared memory is something you are interested in and you really do want to do this project using it for that reason, that's fine, otherwise I would look into using local sockets.

    WRT a linked list, as tabstop says if you are also intending to maintain a database on disk, that is just going to lead to more re-duplication of data. Ie, you will be maintaining the data on-disk separately from, but in parallel with, data in memory. That is an unnecessary hassle. It's also why I think the shared mem idea is sketchy. Let's see if I can explain this difference more clearly:

    1) In the shared mem linked list + file model, you are using a persistent stored data structure as a means of communication, but also mirroring it to disk. Not only is this harder, but it is an illusory exercise: having application 2 serve up files into memory will not save application 1 anytime, because on linux (as I believe most other modern OS's), your "free" memory is used as a file cache. Ie, you might as well just have one application reading straight from "disk", because when the application is under load, it will really be working with the file cache in memory, somewhat freed from the apparent hardware bottleneck -- and ironically then using "unfree" memory to represent the file contents. This amounts to copying stuff back and forth when all you really need to do is read and work with the original.

    2) There are still some good reasons to use 2 applications, however. Eg, that provides greater flexibility, because you could have different possible user interfaces for application 1 (a web interface, a GUI, a terminal app), using a common protocol provided by application 2. But this does not mean that application 2 has to maintain a mirror of the data in shared memory for access by application 1 -- that highly complexifies both of them. IPC using events/messages is much more straight forward. Under that model, application 1 makes specific requests of application 2 and receives specific replies. Eg, application 1 can request an entry be deleted, application 2 deletes the entry on disk (and application 2 gets to enjoy the advantages of the system file cache without having to explicitly allocate and maintain a separate linked list), or application 1 sends application 2 a modified version of an entry to be saved in the database, or application 1 requests a specific entry and application 2 sends it.

    Note that one way or another, the data must be serialized to be saved to disk. This also fits well with the messaging method because it will also need to be serialized for IPC.

    I think perhaps you have it in your mind that using shared mem, so both applications have access to the same data in the same form, is "the obvious and simple way" whereas doing IPC with messages is somehow more abstract and difficult. In reality, that is probably backwards; you will end up needing some kind of messaging anyway (by locking variables or using system signals). Something to think about
    Last edited by MK27; 09-04-2011 at 08:48 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  10. #10
    Registered User
    Join Date
    Sep 2011
    Posts
    23
    @tabstop. We have to save the data to files whenever we insert, modify or delete them immediately. So that if we display them, it should display the updated data(like address book in phone).

  11. #11
    Registered User
    Join Date
    Sep 2011
    Posts
    23
    @MK27.
    It seems to me this is a straightforward client-server model, application 1 being the client (a user interface) and application 2 being a database server.
    What you said is correct. This program should be like a address book in a phone. It should be capable of parallel processing(like in phone, though we open a contact in address book and make a call still we can look for another contacts).
    If we delete a contact it should be automatically updated when we display the contacts. So if we what to delete a particular contact, I think it is better to use linked lists.
    @tapstop & @ MK27 thank you for your suggestions.

  12. #12
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by chaituchemico View Post
    @MK27.
    What you said is correct. This program should be like a address book in a phone. It should be capable of parallel processing(like in phone, though we open a contact in address book and make a call still we can look for another contacts).
    If we delete a contact it should be automatically updated when we display the contacts. So if we what to delete a particular contact, I think it is better to use linked lists.
    @tapstop & @ MK27 thank you for your suggestions.
    Linked lists are great if:
    1. You keep all data in memory, nothing resides in a database or on disk (Pointers don't match up between different programs or different runs of the same program).
    2. You only process the list in order and don't need random access (such as looking up a specific individual).

    In your situation, you might want to consider an array, since it's easy sort and search for elements, which will improve lookups and edits, and it's easy to write to disk, so you can read it back without worrying about pointers not jiving. To "delete" something, you just do a lazy delete -- just mark the record as deleted/invalid, but leave the contents in there. Only throw them away when you need to reuse that spot.

    Also, as MK27 pointed out, shared memory is not the best IPC mechanism for this, but if you're just out for learning, then by all means, keep it up.

  13. #13
    Registered User
    Join Date
    Sep 2011
    Posts
    23
    In your situation, you might want to consider an array, since it's easy sort and search for elements, which will improve lookups and edits, and it's easy to write to disk, so you can read it back without worrying about pointers not jiving. To "delete" something, you just do a lazy delete -- just mark the record as deleted/invalid, but leave the contents in there. Only throw them away when you need to reuse that spot.
    Thank you anduril462. In my code above, I have used arrays to store the data. If I want to delete or modify, can anyone help me how to write code for delete and modify in my program so that if I display the data it should display with the updated data. Thank you

  14. #14
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If you intend to do lazy delete, as mentioned above, you'll need another field in your struct for "valid" or the like to make sure it's still there, and then when outputting (whether to screen or to file) if the valid field is invalid, then skip that record.

    I don't know what you're missing for modify, exactly. You'll need to walk through the array until you find the record to be modified, then modify it.

  15. #15
    Registered User
    Join Date
    Sep 2011
    Posts
    23
    thank you tabstop.
    Is there any other way to pass the 'select' option to the second application, other than defining it in the struct and equating to particular value in its function as i did.
    Code:
    typedef struct 
    {
      int select;
      char lastname[25];
      char firstname[25];
      char address[25];
      char phonenumber[25];
    }addressbook;
    
    void insert()
    {  
       
       for(i=0; i<SIZE; i++)
       {
        a[i].select=1;
        printf("enter details\n");
        printf("enter lastname of person %d:\n", i);
        scanf("%s", a[i].lastname);
        printf("enter firstname of person %d:\n", i);
        scanf("%s", a[i].firstname);
        printf("enter address of person %d:\n", i);
        scanf("%s", a[i].address);
        printf("enter phone number of person %d:\n", i);
        scanf("%s", a[i].phonenumber);
        memcpy(shared_memory, &a[i], sizeof(addressbook));
        system("./address-insert");
       }
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. how to communicate with the web server
    By nadeem athani in forum Linux Programming
    Replies: 1
    Last Post: 03-09-2011, 09:11 AM
  2. Get .cpp and .h files to communicate...
    By yaya in forum C++ Programming
    Replies: 6
    Last Post: 11-25-2008, 12:45 AM
  3. How to communicate with com port?
    By alan85 in forum C++ Programming
    Replies: 7
    Last Post: 12-10-2004, 10:56 PM
  4. Getting two programs to communicate
    By Thantos in forum Windows Programming
    Replies: 4
    Last Post: 08-27-2003, 07:39 AM
  5. can't get MFC to communicate with itself
    By drb2k2 in forum C++ Programming
    Replies: 2
    Last Post: 04-04-2003, 04:06 PM

Tags for this Thread