Best references:
1. Master from the Internet.
2. UNP V2 posix ipc chapters 2, 5, 10, and 13.
3. Linux man command.
Remember Master Steven s first. So start ~~~~ Although posix ipc is a standard IPC and a future trend, most applications are still using the System v ipc Mechanism. I have not introduced it at all from apue and deep understanding of Linux kernel architecture. ulk only introduced POSIX message queue.
Article 1:Posix ipc uses posix ipc name for flag.
Posix.1 describes the name of posix ipc as follows: it may be a real path name in a file system, or it may not. The first parameter of the mq_open, sem_open, and shm_open functions is such a name. This is the description in section 2.2 of unpv2. Not very detailed. Many of the books are inconsistent with the current Linux systems ~~
Sem_open prototype: sem_t * sem_open (const char * Name, int Oflag ,...);
In Linux, sem_open is created in the/dev/SHM directory (Linux/dev/SHM is a special tmpfs, just like/proc,/sys, run the mount command) and add SEM. therefore, if the name is "hehe", the created file is/dev/SHM/SEM. hehe.
See nptl/sem_open.c source code in glibc. If the name parameter starts with '/', it will be ignored.
- /* Construct the filename .*/
- While (name [0] = '/')
- ++ Name;
Conclusion:
1. sem_open
The name parameter can be a string that starts with or equal to 0 '/' (all ignored) and cannot contain the '/' character except the start. (For example, if the name parameter is hehe/Hehe, even if the path/dev/SHM/hehe/exists, it is not correct. Why not? I have not understood the source code, if you want to understand it, go back to it ,:-));
2. shm_open
What is different from sem_open is that name can be a path, that is, the parameter can contain '/' except the beginning, but the premise is that the directory in the path must exist.
3. mq_open
Strict requirements: The parameter can only be a "/+ String", that is, it must start with '/' and the string cannot contain '/';
Article 2: prerequisites
-LRT must be added when semaphores are running.
For message queues, manually mount the mqueue file system. The command is as follows: (see man 7 mq_overview for details)
Mkdir/dev/mqueue Mount-T
Mqueue NONE/dev/mqueue
Article 3: running results
The message queue generates files in the/dev/mqueue directory.
The files generated by semaphores and shared memory are in the/dev/SHM directory.
Article 4: POSIX message queue mechanismImplementation of POSIX Message Queue
See Chapter 19th of ulk. The basic principle is: the message queue descriptor mqd uses the fget function of VFS to locate the mqueue_inode_info containing the node through the Message Queue file -----> corresponding to/dev/mqueue. Each message queue corresponds to an mqueue_inode_info, which contains inode objects, while inode corresponds to a file in the/dev/mqueue/special file system. Messages in the queue are placed in the one-way linked list in mqueue_inode_info. The message is msg_msg, which is exactly the same as the system vipc message descriptor.
# Include <mqueue. h>
Mqd_t mq_open (const char * Name, int Oflag,.../* mode_t mode, struct mq_attr_t * ATTR */); // create a file named name under/dev/mqueue
Int mq_close (mqd_t mqdes );
Int mq_unlink (const char * Name); // The Directory necklace of the file indexed by name minus Stat. nlink 1;
Struct mq_attr
{
Long int mq_flags;/* Message Queue flags .*/
Long int mq_maxmsg;/* Maximum number of messages .*/
Long int mq_msgsize;/* maximum Message Size of a message .*/
Long int mq_curmsgs;/* Number of messages currently queued .*/
Long int _ pad [4];
}; // The value of flags and curmsgs is automatically ignored in the fourth parameter for mq_open;
Int mq_getattr (mqd_t mqdes, struct mq_attr * mqstat );
Int mq_setattr (mqd_t _ mqdes, const struct mq_attr * restrict mqstat, struct mq_attr * restrict omqstat );
/* Receive the oldest from highest priority messages in Message Queue mqdes .*/
Ssize_t mq_receive (mqd_t mqdes, char * msg_ptr, size_t msg_len, unsigned int * msg_prio );
/* Add message pointed by msg_ptr to message queue mqdes .*/
Int mq_send (mqd_t mqdes, const char * msg_ptr, size_t msg_len, unsigned int msg_prio );
The principles of these functions are as follows:Process A creates a Message Queue file under/dev/mqueue/through mq_open, and then processes A, B, C, and D open it through mq_open, then send and receive information through mq_send and mq_receive using this file as the media (Message Queue. Mq_getatt and mq_setatt obtain and set Message Queue attributes.
Union sigval {/* data passed with notification */
Int sival_int;/* integer value */
Void * sival_ptr;/* pointer value */
};
Struct sigevent {
Int sigev_notify;/* Notification Method */
Int sigev_signo;/* notification signal */
Union sigval sigev_value;/* data passed with notification */
Void (* sigev_policy_function) (Union sigval);/* function for thread notification */
Void * sigev_notify_attributes;/* thread function attributes */
};
/* Register notification issued upon message arrival to an empty Message Queue mqdes .*/
Int mq_notify (mqd_t mqdes, const struct sigevent * notification); // Ubuntu 10.10 tests this function to register a message in the original queue. The newly generated data is not reflected by the registered process. Only when the message queue is empty is registered. When a new message is generated, the registration process will reflect ~~~
How does the mq_notify function work when the parameter notification> sigev_notify = sigev_signal?Use the mqd, notification-> sigev_signo parameters, and the calling process itself to associate the Message Queue with the process through a signal. When the queue is empty, place a message to send a signal to the registration process, and the process that receives the signal delivers the signal (that is, call the signal processing function to process it ,:-).).
How does the mq_notify function work when the parameter notification-> sigev_notify = sigev_thread isThe parameter mqd, notification-> sigev_policy_function and the parameter notification-> sigev_value of the thread function and the attribute notification-> sigev_policy_attributes of the newly created thread are used, associate A Message Queue with a thread through a signal. When the queue is empty, this thread is called to process messages when a message is placed.
Both the signal version and the thread version must be registered again after a message is accepted.
(Random entry: int sigwait (const sigset_t * Set, int * sig); // synchronous waiting for an asynchronous event: we are using signals, but it does not involve asynchronous signal processing programs !)
Article 5: Implementation of POSIX shared memory mechanism psoix shared memory Zone
It is built on the call function of the MMAP system.
# Include <sys/Mman. h>
Int shm_open (const char * Name, int Oflag, mode_t mode); // The mode parameter of shm_open must always be specified and can be set to 0.
Int shm_unlink (const char * Name );
# Include <unistd. h>
# Include <sys/types. h>
Int ftruncate (int fd, off_t length );
// If the file previusly was larger than this size, the extra data is lost. if the file previusly was shorter, it is extended, and the extended part reads as null bytes ('/0 '). (Man ~~~)
# Include <sys/types. h>
# Include <sys/STAT. h>
Int fstat (int fd, struct stat * BUF );
The basic principles of POSIX shared memory are as follows:Process A creates a file named "parameter name" in the/dev/SHM/directory through shm_open, processes A, B, C, and D can call shm_open to open the file under/dev/SHM/with the same name parameter, additionally, you can use the ftruncate function to change the file size. And get stat. st_size through fstat to get the overall size of the file for MMAP parameters. Use the MMAP function to map the memory space of the calling process of this file. Obtain an address inside the calling process for read/write operations.
Article 6: Implementation of POSIX semaphores
POSIX semaphores are often used for thread synchronization (unknown semaphores), and System V semaphores are often used for process synchronization. There are two types of POSIX semaphores: famous semaphores and unknown semaphores (memory-based semaphores ). Multiple Threads in a process share and use a semaphore based on memory (that is, memory space of the Process ^_^. Multiple processes share and use the famous semaphores in the shared memory area. Unpv2 provides three implementation methods for POSIX famous semaphores Based on FIFO, memory ing I/O + mutex lock + condition variable, and System V semaphores. After reading nptl/sem_open.c, POSIX semaphores on Linux are also implemented based on MMAP. POSIX unknown semaphores are implemented simply by allocating a sem_t type memory space in the process space to call sem_init for initialization.
Semaphores can also be divided into two-value semaphores-Initialize semaphores to 1 and count semaphores-usually initialized to a certain N value that represents the number of resources. However, this distinction is not found in the code that implements semaphores.
Master Steven s listed the differences between semaphores, mutex locks, and condition variables in unpv2:
1. The mutex lock is always unlocked by the lock thread, but the P operation of the semaphore does not need to be executed by the same thread that has executed its V operation.
2. The mutex lock is either locked or unlocked. (Binary status, similar to binary semaphore ).
3. Because there is a state value (n) In the semaphore, the P operation of the semaphore always leaves their memories (that is, it is remembered-N programming n + 1 ). However, when a signal is sent to a condition variable, if there is no thread waiting on the condition variable, the signal will be lost.
# Include <semaphore. h>
// Functions used by memory-based semaphores
Int sem_init (sem_t * SEM, int pshared, unsigned int value );
Int sem_destroy (sem_t * _ SEM );
// Functions used by famous semaphores
Sem_t * sem_open (const char * Name, int Oflag ,...);
Int sem_close (sem_t * SEM );
Int sem_unlink (const char * Name );
// Shared Functions
Int sem_wait (sem_t * SEM );
Int sem_trywait (sem_t * SEM );
Int sem_post (sem_t * SEM); // This function is a signal security function (unpv2)
Int sem_getvalue (sem_t * restrict SEM, int * restrict sval );
Int sem_timedwait (sem_t * restrict SEM, const struct timespec * restrict abstime );
The basic principles of POSIX semaphores are: P and V Operations!
See http://wangcong.org/blog? P = 591 http://www.cnblogs.com/super119/archive/2010/12/13/1904392.html