write in front
I have to say that deadline is really the first productive force. But what was done was really unsightly, and spent the morning rewriting the code.
Experimental content
进程通信的邮箱方式由操作系统提供形如 send()和 receive()的系统调用来支持,本实验要求学生首先查找资料了解所选用操作系统平台上用于进程通信的系统调用具体形式,然后使用该系统调用编写程序进行进程间的通信,要求程序运行结果可以直观地体现在界面上。在此基础上查找所选用操作系统平台上支持信号量机制的系统调用具体形式,运用生产者与消费者模型设计实现一个简单的信箱,该信箱需要有创建、发信、收信、撤销等函数,至少能够支持两个进程互相交换信息,比较自己实现的信箱与操作系统本身提供的信箱,分析两者之间存在的异同。
Background knowledge??
Message Queuing
What is Message Queuing
Message Queuing provides a way to send a block of data from one process to another. Each block of data is considered to contain a type, and the receiving process can independently receive data structures that contain different types. We can avoid the synchronization and blocking problems of named pipes by sending messages. But Message Queuing, like named Pipes, has a maximum length limit for each block of data.
Linux uses macro Msgmax and MSGMNB to limit the maximum length of a message and the maximum length of a queue.
- How to use Message Queuing in Linux
Linux provides a series of function interfaces for Message Queuing that allow us to easily use it for interprocess communication. Its usage is similar to the other two system V pic mechanisms, i.e. semaphores and shared memory.
- Msgget () function
This function is used to create and access a message queue. Its prototype is:
int msgget(key_t key, int msgflg);
It returns an identifier for a message queue named key (nonzero integer), which returns 1 on failure.
- MSGSND () function
This function is used to add messages to the message queue. Its prototype is:
int msgsend(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);
If the call succeeds, a copy of the message data is placed in the message queue and returns 0, returning 1 on failure.
- MSGRCV () function
This function is used to obtain a message from a message queue, and its prototype is:
int msgrcv(int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msgflg);
When the call succeeds, the function returns the number of bytes placed in the receive buffer, the message is copied to the user-allocated buffer that is pointed to by msg_ptr, and the corresponding message in the message queue is deleted. Returns-1 on failure.
- Msgctl () function
This function is used to control Message Queuing, which is similar to the SHMCTL function of shared memory, and its prototype is:
int msgctl(int msgid, int command, struct msgid_ds *buf);
Returns 0 on success, 1 on failure.
??
Signal Volume
- What is Semaphore
To prevent a series of problems that arise from the simultaneous access of multiple programs to a shared resource, we need a method that can be authorized by generating and using tokens, and at any one time there can be only one critical region that executes thread access code. A critical region is a code that performs data updates that needs to be executed exclusively. And semaphores can provide such an access mechanism, so that a critical section at the same time only one thread is accessing it, that is, the semaphore is used to attune process access to shared resources.
- The semaphore mechanism of Linux
Linux provides a well-designed set of semaphore interfaces to operate on semaphores, which are not just for binary semaphores, but are described below, but note that these functions are used to manipulate the set of semaphore values . They are declared in the header file sys/sem.h.
- Semget () function
Its role is to create a new semaphore or to obtain an existing semaphore, the prototype is:
int semget(key_t key, int num_sems, int sem_flags);
A corresponding signal identifier (not 0) was returned successfully, and the failure returned-1.
- Semop () function
Its function is to change the value of the semaphore, the prototype is:
int semop(int sem_id, struct sembuf *sem_opa, size_t num_sem_ops);
- Semctl () function
This function is used to control the semaphore information directly, and its prototype is:
int semctl(int sem_id, int sem_num, int command, ...);
??
Shared Memory
- What is shared memory
by definition, shared memory allows two unrelated processes to access the same logical memory. Shared memory is a very efficient way to share and pass data between two running processes. Memory that is shared between different processes is usually scheduled as the same piece of physical memory. Processes can connect the same piece of shared memory to their own address space, and all processes can access the addresses in the shared memory as if they were allocated by the C-language function malloc (). If a process writes data to shared memory, the changes will immediately affect any other process that can access the same piece of shared memory.
Special reminder: Shared memory does not provide a synchronization mechanism, that is, there is no automatic mechanism to prevent the second process from reading the shared memory until the first process finishes writing it. So we usually need to use other mechanisms to synchronize access to shared memory, such as the amount of semaphores mentioned earlier.
- Use of shared memory
As with semaphores, a set of function interfaces is provided in Linux for use with shared memory, and interfaces with shared coexistence are very similar to semaphores and are simpler than interfaces that use semaphores. They are declared in the header file sys/shm.h.
- Shmget () function
This function is used to create shared memory, which is prototyped as:
int shmget(key_t key, size_t size, int shmflg);
On success, a shared memory identifier (non-negative integer) associated with key is returned for subsequent shared memory functions. The call failed to return-1.
- Shmat () function
When the shared memory is created for the first time, it cannot be accessed by any process, and the Shmat () function is used to initiate access to the shared memory and to connect the shared memory to the address space of the current process. Its prototype is as follows:
void *shmat(int shm_id, const void *shm_addr, int shmflg);
On success, returns a pointer to the first byte of shared memory if the call fails to return-1.
- SHMDT () function
This function is used to detach shared memory from the current process. Note that separating shared memory is not removing it, just making that shared memory no longer available to the current process. Its prototype is as follows:
int shmdt(const void *shmaddr);
Returns 0 on successful invocation and 1 on failure.
- Shmctl () function
As with the semaphore Semctl () function, it is used to control shared memory, which is prototyped as follows:
int shmctl(int shm_id, int command, struct shmid_ds *buf);
Resources
All of the above information is from the following websites:
- Linux interprocess communication (v): Semaphore Semget (), Semop (), Semctl ()
- Linux interprocess communication (vi): Shared memory Shmget (), Shmat (), SHMDT (), Shmctl ()
- Linux interprocess communication (vii): Message Queuing Msgget (), Msgsend (), MSGRCV (), Msgctl ()
Experimental results
- Message Queuing
- Signal Volume + Shared memory
Full code
? Linux-interprocesscommunication
Summarize
- Insufficient
- No graphical interface
- Process communication implemented with semaphores and shared memory can only send digital messages
- When creating a shared memory space, set permissions for easy setting to 0666 (each process is readable and writable), you should set the user to read only and not write, other can only write and not read
- Message Queuing does not have a test MSGRCV () function that alters the receive priority by changing the Msgtype parameter.
> Msgtype can achieve a simple receive priority. If Msgtype is 0, it gets the first message in the queue. If its value is greater than 0, it gets the first information with the same message type. If it is less than 0, it gets the first message with a type equal to or less than the absolute value of Msgtype.
--referencing from Linux interprocess communication (vii): Message Queuing Msgget (), Msgsend (), MSGRCV (), Msgctl ()
- Similarities and differences between two ways to realize interprocess communication
- XOR: Message Queuing does not require semaphores to control synchronization and mutex issues, and it can easily change the receive priority, while shared memory can only simply receive messages sorted by time.
- Same: A process receives the same message as another process sends.
- Experience
- Since the semaphore interface functions provided by Linux operate on a set of semaphores, most of the parameters need to be specified to operate on which semaphore in a group
- The shared memory only holds the message buffer, and the value of the mailbox header is still stored in the respective process.
If there are deficiencies, please correct me!
Linux interprocess communication (Message Queue/semaphore + shared memory)