1 共享内存
在Linux或者类Unix的系统下,共享内存是三大进程间通信方式之一。一个共享内存段被kernel创建,并且映射到用户态进程的数据段,使用共享内存通信最大的好处是效率很高,因为进程可以直接读写内存,而不需要任何数据的拷贝。这种方式很适合大量传感器数据的传输,比如camera frame.
2 System V and POSIX Shared Memory
共享内存有两种实现方式:System V shared memory and the newer POSIX shared memory,
本文会介绍使用 System V shared memory方式来完成server and client processes communicating。
3 System V IPC key
To use a System V IPC mechanism, we need a System V IPC key. The ftok function, which does the job, is
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok (const char *pathname, int proj_id);
4 System V Shared Memory Calls
4.1 shmget
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget (key_t key, size_t size, int shmflg);
4.2 shmat
#include <sys/types.h>
#include <sys/shm.h>
void *shmat (int shmid, const void *shmaddr, int shmflg);
4.3 shmdt
#include <sys/types.h>
#include <sys/shm.h>
int shmdt (const void *shmaddr);
4.4 shmctl
#include <sys/ipc.h>
#include <sys/shm.h>
int shmctl (int shmid, int cmd, struct shmid_ds *buf);
The shmctl call is for control operations of a System V shared memory segment identified by the shmid identifier, returned by an earlier shmget call. The data structure for shared memory segments in the kernel is,
struct shmid_ds {
struct ipc_perm shm_perm; /* Ownership and permissions */
size_t shm_segsz; /* Size of segment (bytes) */
time_t shm_atime; /* Last attach time */
time_t shm_dtime; /* Last detach time */
time_t shm_ctime; /* Last change time */
pid_t shm_cpid; /* PID of creator */
pid_t shm_lpid; /* PID of last shmat(2)/shmdt(2) */
shmatt_t shm_nattch; /* No. of current attaches */
...
};
5 An example: Client-Server communication using System V Shared Memory
5.1 client
/*
*
* consumer.c: Print strings in the shared memory segment
* (Consumer process)
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
// Buffer data structures
#define MAX_BUFFERS 10
#define SHARED_MEMORY_KEY "/tmp/shared_memory_key"
#define SEM_MUTEX_KEY "/tmp/sem-mutex-key"
#define SEM_BUFFER_COUNT_KEY "/tmp/sem-buffer-count-key"
#define SEM_SPOOL_SIGNAL_KEY "/tmp/sem-spool-signal-key"
#define PROJECT_ID 'K'
struct shared_memory {
char buf [MAX_BUFFERS] [256];
int buffer_index;
int buffer_print_index;
};
void error (char *msg);
int main (int argc, char **argv)
{
key_t s_key;
union semun
{
int val;
struct semid_ds *buf;
ushort array [1];
} sem_attr