• 欢迎浏览“String me = Creater\忠实的资深Linux玩家;”,请文明浏览,理性发言,有侵犯你的权益请邮件我(creater@vip.qq.com).
  • 把任何的失败都当作一次尝试,不要自卑;把所有的成功都想成是一种幸运,不要自傲。
  •    5年前 (2013-08-28)  Linux |   1 条评论  8 
    文章评分 0 次,平均分 0.0

    共享内存是速度较快的IPC了。以下提供一个共享内存类。代码很简单,不用多的解释。
    robot_shm_buffer.h

    #ifndef ATU_SHM_BUFFER_H_
    #define ATU_SHM_BUFFER_H_
    #include <string>
    #include <fcntl.h>
    #include <semaphore.h>
    
    namespace atu_libs {
    
    namespace atu_shm_buffer {
    
    const u_int c_default_buffer_len = 256;
    
    class atu_shm_buffer {
    public:
    	/*
    	 *  Constructor of atu_shm_buffer.
    	 *  @name:     the name of the shared memory.
    	 *  @len:      if first created, specify the length of the shared memroy.
    	 *  @create:   true create a new shared memory, false link to an exist shared memory.
    	 */
    	atu_shm_buffer(const char *name, size_t len = c_default_buffer_len, bool create = false);
    	virtual ~atu_shm_buffer();
    
    	/*
    	 *  Get the name of the shared memory.
    	 *  Return value: the name of the shared memory.
    	 */
    	inline const char * get_name(void) { return m_name.c_str(); }
    	/*
    	 *  Get the length of the shared memory.
    	 *  Return value: the length of the shared memory.
    	 */
    	inline size_t get_len(void) { return m_len; }
    
    	/*
    	 *  Read from shared memory. Use a semaphore with the same name to synchronize.
    	 *  @buf:    the point to a buffer, the buffer must be allocated.
    	 *  @len:    the length of bytes read from shared memory.
    	 */
    	void read(char *buf, size_t len);
    	/*
    	 *  Write bytes to shared memroy. Use a semaphore with the same name to synchronize.
    	 *  @content:  the point to a buffer with contents, the buffer must be allocated.
    	 *  @len:      the length of bytes write to shared memory.
    	 */
    	void write(const void *content, size_t len);
    	/*
    	 *  Unlink the shared memory and semaphore from linux kernel.
    	 */
    	void unlink(void);
    private:
    	void *m_buf;
    	size_t m_len;
    	int m_fd;
    	std::string m_name;
    
    	sem_t *m_sem;
    	struct stat m_stat;
    };
    }
    }
    
    #endif /* ATU_SHM_BUFFER_H_ */

    robot_shm_buffer.cpp

    #include <sys/mman.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
    #include <assert.h>
    #include "robot_shm_buffer.h"
    
    namespace atu_libs {
    
    namespace atu_shm_buffer {
    /*
     *  Constructor of atu_shm_buffer.
     *  @name:     the name of the shared memory.
     *  @len:      if first created, specify the length of the shared memroy.
     *  @create:   true create a new shared memory, false link to an exist shared memory.
     */
    atu_shm_buffer::atu_shm_buffer(const char *name, size_t len, bool create)
    : m_buf(NULL)
    , m_len(len)
    , m_name(name)
    {
    	assert(NULL != name);
    
    	int ret(0);
    
    	//Link to the shared memory.
    	if (create)
    	{
    		m_fd = shm_open(name, O_RDWR | O_CREAT, 0644);
    
    		//create a semaphore for w/r operation.
    		m_sem = sem_open(name, O_CREAT, 0644, 1);
    		if (SEM_FAILED == m_sem)
    		{
    			fprintf(stderr, "Failed to create semaphore %s!\n", name);
    			return;
    		}
    		//set the size of the shared memory.
    		ret = ftruncate(m_fd, len);
    		if (-1 == ret)
    		{
    			fprintf(stderr, "Failed to re-size shared memory buffer %s!\n", name);
    			return;
    		}
    	}
    	else
    	{
    		m_fd = shm_open(name, O_RDWR, 0644);
    		//set a sem for w/r operation.
    		m_sem = sem_open(name, O_RDWR);
    		if (SEM_FAILED == m_sem)
    		{
    			fprintf(stderr, "Failed to create semaphore %s!\n", name);
    			return;
    		}
    	}
    	if (-1 == m_fd)
    	{
    		fprintf(stderr, "Failed to create shared memory buffer %s!\n", name);
    		return;
    	}
    
    	//get shared memory status.
    	ret = fstat(m_fd, &m_stat);
    	if (-1 == ret)
    	{
    		fprintf(stderr, "Failed to get status of shared memory!\n");
    		return;
    	}
    	m_len = m_stat.st_size;
    
    	//map the shared memory to buffer.
    	m_buf = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, m_fd, 0);
    	if (MAP_FAILED == m_buf)
    	{
    		perror("Failed to map shared memory to process!");
    		return;
    	}
    
    	//If the shared memory is created for the first time, initialize it.
    	if (create)
    	{
    		memset(m_buf, 0, len);
    	}
    }
    
    atu_shm_buffer::~atu_shm_buffer() {
    	if (-1 != m_fd)
    	{
    		munmap(m_buf, m_len);
    	}
    
    	//!!!If you want to unlink semaphore and shared memory, please use function unlink().
    }
    
    /*
     *  Unlink the shared memory and semaphore from linux kernel.
     */
    void atu_shm_buffer::unlink(void)
    {
    	if (MAP_FAILED != m_buf)
    	{
    		sem_unlink(m_name.c_str());
    		shm_unlink(m_name.c_str());
    	}
    }
    
    /*
     *  Read from shared memory. Use a semaphore with the same name to synchronize.
     *  @buf:    the point to a buffer, the buffer must be allocated.
     *  @len:    the length of bytes read from shared memory.
     */
    void atu_shm_buffer::read(char *buffer, size_t len)
    {
    	if (len > m_len)
    	{
    		fprintf(stderr, "[read] Buffer is truncated! From %d to %d bytes.\n",
    				(int)len, (int)m_len);
    		len = m_len;
    	}
    	sem_wait(m_sem);
    	memcpy((void *)buffer, m_buf, len);
    	sem_post(m_sem);
    }
    
    /*
     *  Write bytes to shared memroy. Use a semaphore with the same name to synchronize.
     *  @content:  the point to a buffer with contents, the buffer must be allocated.
     *  @len:      the length of bytes write to shared memory.
     */
    void atu_shm_buffer::write(const void* buffer, size_t len)
    {
    	if (len > m_len)
    	{
    		fprintf(stderr, "[write] Buffer is truncated! From %d to %d bytes.\n",
    				(int)len, (int)m_len);
    		len = m_len;
    	}
    	sem_wait(m_sem);
    	memcpy(m_buf, buffer, len);
    	sem_post(m_sem);
    }
    
    }
    }
     

    除特别注明外,本站所有文章均为String me = "Creater\忠实的资深Linux玩家";原创,转载请注明出处来自http://unix8.net/home.php/1853.html

    关于

    发表评论

    暂无评论

    切换注册

    登录

    忘记密码 ?

    切换登录

    注册

    扫一扫二维码分享