LinuxIPC, FIFO, and shm

Source: Internet
Author: User
Occasionally, a function is required to debug the function: adjust some simple parameters based on the feedback. There are two requirements: 1. do not interrupt the program, and do not pause waiting for input every time; 2. do not need to re-

Occasionally, a function is required to debug the function: adjust some simple parameters based on the feedback. There are two requirements: 1. do not interrupt the program, and do not pause waiting for input every time; 2. do not re-compile the program and run the program. In this case, the requirement is basically multi-process, listening, and IPC.

The first thing that comes to mind is to use environment variables. The getenv () function is basically used to obtain the corresponding environment variable. During use, it is impossible to find out. Because environment variables are user-level, and each console is equivalent to a user, environment variables cannot be communicated.

Then I saw the concept of IPC. I checked and found pipelines, sockets, signals, shared memory, and message queues.

The pipelines and shared memory used are based on the shared memory. I have to say that linux is too clever to worship this abstract ability. Files in the program are abstracted as a piece of memory, and files have sharing functions, which are great.

Shm is used first, because it is claimed to be fast. Create a file under/dev/shm/. This folder exists completely in the memory (swap is sometimes used. There won't be too many disk IO, so it will be faster. The problem is that you need to use a lock to ensure the atomicity of read/write. Even reading incomplete data. So I don't like it. Shmget (), shmat (), shmctl (), and shmdt (). The lock uses similar semget (), semctl (), semop (), and so on. Good results, but complicated logic.

PV operation:

 

int p(int semid){struct sembuf op;op.sem_num = 0;op.sem_op = -1;return semop(semid, &op, 1);}int v(int semid){struct sembuf op;op.sem_num = 0;op.sem_op = 1;return semop(semid, &op, 1);}

Sender:

 

#include
 
  #include
  
   #include
   
    #include
    
     #include
     
      #include
      
       #include
       
        #include"statics.h"#include"pv.h"int main(){int shmid, semid;key_t key;message *msg;if((key = ftok(PATH,ID))==-1){printf("ftok error");return -1;}if((shmid = shmget(key, 4096, IPC_CREAT)) == -1){printf("shm error");return -1;}if((msg = shmat(shmid,NULL,0)) == (message*)-1){printf("shmat error");return -1;}if((semid = semget(key, 1, IPC_CREAT)) == -1){printf("sem error");return -1;}union semun option;option.val = 1;semctl(semid, 0, SETVAL, option);p(semid);msg->type = 0;msg->length = 1;((int*)msg->data)[0] = 2;v(semid);shmdt(msg);return 0;}
       
      
     
    
   
  
 

Reciever:

 

#include
 
  #include
  
   #include
   
    #include
    
     #include
     
      #include
      
       #include
       
        #include"statics.h"#include"pv.h"int main(){int shmid, semid;key_t key;message *msg;if((key = ftok(PATH,ID))==-1){perror("ftok error");return -1;}if((shmid = shmget(key, 4096, IPC_CREAT)) == -1){perror("shm error");return -1;}if((msg = shmat(shmid,NULL,0)) == (message*)-1){perror("shmat error");return -1;}if((semid = semget(key, 1, IPC_CREAT)) == -1){perror("sem error");return -1;}union semun option;option.val = 1;semctl(semid, 0, SETVAL, option);while(1){p(semid);if(0 == msg->type){int *arr = (int*)msg->data;if(msg->length == 1){int val = arr[0];if(2 == val)break;}}v(semid);sleep(1);printf(".");}shmdt(msg);printf("exit\n");return 0;}
       
      
     
    
   
  
 
Another problem is the release time and location of sem. because the time of both parties is not certain, there will be problems.

The named pipe is used. the named pipe is a visible file. after running, the pipe is empty and the file size is 0 ,. It should also be pure memory behavior. Named pipelines are mainly mkfifo (), open (), close (), read (), write (), and are the usage modes of files. Although the operation is not atomic (a part may be written and another part of the data), the file lock mechanism should take effect. There is no danger of reading old data. It is not much simpler to use.

Sender:

 

#include
 
  #include
  
   #include
   
    #include
    
     #include
     
      #include"statics.h"int main(){message msg;int file, count;if((mkfifo(PATH, O_CREAT) < 0)&&(EEXIST != errno)){perror("can't create fifo");return -1;}file = open(PATH, O_WRONLY, 0);if(-1 == file){perror("file wrong");}msg.type = 0;msg.length = 1;((int*)msg.data)[0] = 2;count = write(file, &msg, sizeof(msg));if(-1 == count){perror("can't write");}printf("count: %d\n", count);close(file);return 0;}
     
    
   
  
 

Reciever:

 

 

#include
 
  #include
  
   #include
   
    #include
    
     #include
     
      #include"statics.h"int main(){message msg;int file, count;if((mkfifo(PATH, O_CREAT) < 0)&&(EEXIST != errno)){perror("can't create fifo");return -1;}file = open(PATH, O_RDONLY|O_NONBLOCK, 0);while(1){sleep(1);printf(".");count = read(file, &msg, sizeof(msg));if(-1 == count && EAGAIN == errno){continue;}else{if(0 == msg.type){int *arr = (int*)msg.data;if(msg.length == 1){int val = arr[0];if(2 == val)break;}}}}printf("exit\n");return 0;}
     
    
   
  
 
The problem is that an MPs queue file is displayed in the file system, and the file size is relatively good.

Some very small and interesting problems encountered in the process:

0. fork () function. this function copies the stack content, that is to say, copying the space that you run will produce the effect of calling two functions at a time. It is very interesting, so two threads with 0 values will be returned, and the main thread with val (> 0) will be returned. Very interesting. In addition, the entire running mode is like the MPI pole, and finally understands why MPI has such an unreasonable design.

1. printf () is not output, and printf ('.') is used in the middle to indicate the running status of the receiver. But there is basically no output until the process ends. The reason is that printf flush by row. it takes too long to fill a row, so no point is visible. There are two solutions: use stderr output; fflush (stdout) force flush.

2. the header file is included multiple times during make, which may be defined multiple times. Solution: declare only the extern variable in the header file, and create a c file to define the variable. You do not need to add extern, but note that const and other modifiers must be consistent.

I will do a speed test tomorrow, and I haven't thought of a good method yet. Think about ing...

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.