SHM

/* File: shm.c shm.h
*                    Author:DingChongChong
*                    Description:Provide the shared memory operations
*                    Release: V1.0 2016/04/12
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/sem.h>
#include<sys/shm.h>

#include "shm.h"


/**********GB************/
static char * shmBaseAddr=NULL;
#define SHM_SIZE (4*1024*1024)+sizeof(partition_t)

/*********sem**********/
key_t sem_key=20160401;
int sem_id;
 union semun {
               int              val;   
               struct semid_ds *buf;    
               unsigned short  *array; 
               struct seminfo  *__buf; 
};


int semaphore_init()
{
sem_id=semget(sem_key,1,0666|IPC_CREAT);
if(-1 == sem_id)
return -1;
union semun sem_un;
sem_un.val=1;
return semctl(sem_id,0,SETVAL,sem_un);
}
int semaphore_del()
{
union semun sem_un;
return semctl(sem_id,0,IPC_RMID,sem_un);
}
int semaphore_p()
{
struct sembuf sem_buf;
sem_buf.sem_num=0;
sem_buf.sem_op=-1;
sem_buf.sem_flg=SEM_UNDO;
return semop(sem_id,&sem_buf,1);
}
int semaphore_v()
{
struct sembuf sem_buf;
sem_buf.sem_num=0;
sem_buf.sem_op=1;
sem_buf.sem_flg=SEM_UNDO;
return semop(sem_id,&sem_buf,1);
}




/*********shm*************/

key_t shm_key=20160402;
int shm_id;

/*
* Func: shm_init()
* Param:
* memsetFlag : 1 reset the partition table,else not reset.
*/
int shm_init(unsigned int memsetFlag)
{
if(-1==semaphore_init())
return -1;
 
if(-1 == (shm_id=shmget(shm_key,SHM_SIZE,0666|IPC_CREAT)))
return -1;

if(NULL ==(shmBaseAddr=shmat(shm_id,NULL,0)))
return -1;

if(1==memsetFlag)
{
memset(shmBaseAddr,0,SHM_SIZE);
partition_t partition;
partition.sectNum=0;
partition.remainSpace=SHM_SIZE-sizeof(partition_t);
semaphore_p();
memcpy((unsigned char *)shmBaseAddr,(unsigned char *)&partition,sizeof(partition_t));
semaphore_v();
}
return 1;
}




/*
*
* Func: register_section()
* Params:
* sectKey : The unique key id witch stand for the section you need to register.for sections key list ,you may use AN enum struct ,the first item must start with '1';.
* dataSize: In this section ,dataSize is a record size,you can use 'size(struct)'
* dataNum:In this section ,dataNum you need to store.
* return : 1 success;-1 failed.
*
* example:
* typedef enum _SECTION_LIST
* {
* SECTION_SECT1=1,
* SECTION_SECT2,
* SECTION...
* }SectionList;
*
* typedef struct _DATA_YOU_NEED
* {
* int ...
* }MyData;
* int main()
* {
* if(1!=shm_init(1))
* printf("shm init failed!\n");
* else
* {
* register_section(SECTION_SECT1,sizeof(MyData),100);
* }
* }
*
*/
int register_section(int sectKey,int dataSize,int dataNum)
{
partition_t partition;
semaphore_p();
memcpy((unsigned char *)&partition,(unsigned char *)shmBaseAddr,sizeof(partition));
semaphore_v();
if( (partition.sectNum == SECTION_NUM)  || (partition.remainSpace  <  (dataSize * dataNum)) )
return -1;
else
{ int i;
for(i=0;i<partition.sectNum;i++)
if(partition.sectTable[i].sectKey == sectKey)
return -1;
partition.sectTable[partition.sectNum].sectKey=sectKey;
partition.sectTable[partition.sectNum].maxNum=dataNum;
partition.sectTable[partition.sectNum].usedNum=0;
partition.sectTable[partition.sectNum].dataSize=dataSize;
partition.sectTable[partition.sectNum].sectOffset=SHM_SIZE-partition.remainSpace;
partition.sectNum++;
partition.remainSpace-=(dataSize * dataNum );
semaphore_p();
memcpy((unsigned char *)shmBaseAddr,(unsigned char *)&partition,sizeof(partition_t));
semaphore_v();

}
return 1;
}


/*   Func :  shm_read()
* Params:
* sectKey:the key of sections
* dest:the address of where you need to keep
*     Description:this function read data by "index" ;index>=1
*/
int shm_read(int sectKey,void *dest,int index)
{
if(index<=0)
return -1;
partition_t partition;
semaphore_p();
memcpy((unsigned char *)&partition,(unsigned char *)shmBaseAddr,sizeof(partition_t));
semaphore_v();


int i;
for(i=0; i < partition.sectNum; i++)
if( partition.sectTable[i].sectKey == sectKey )
break;
if(i != partition.sectNum && (index<=partition.sectTable[i].usedNum))
{
semaphore_p();
memcpy((unsigned char *)dest, (unsigned char *)(shmBaseAddr+partition.sectTable[i].sectOffset+partition.sectTable[i].dataSize * (index-1)), partition.sectTable[i].dataSize);  
semaphore_v();
}
else
return -1;
return 1;

}


/*   Func : shm_write()
*     Description:this function write data at last position.
*/
int shm_write(int sectKey,void *src)
{
partition_t partition;
semaphore_p();
memcpy((unsigned char *)&partition,(unsigned char *)shmBaseAddr,sizeof(partition));
semaphore_v();
int i;
for(i=0; i < partition.sectNum; i++)
if( partition.sectTable[i].sectKey == sectKey )
break;
if(i != partition.sectNum)
{
if(partition.sectTable[i].usedNum==partition.sectTable[i].maxNum)
return -1;
else
{
semaphore_p();
memcpy((unsigned char *)(shmBaseAddr+partition.sectTable[i].sectOffset+partition.sectTable[i].dataSize * partition.sectTable[i].usedNum),(unsigned char *)src,partition.sectTable[i].dataSize);
semaphore_v();
partition.sectTable[i].usedNum++;
}
}
semaphore_p();
memcpy((unsigned char *)shmBaseAddr,(unsigned char *)&partition,sizeof(partition));
semaphore_v();
return 1;
}


/*   Func : shm_writeEx()
*     Description:this function write data at last position.
*/
int shm_writeEx(int sectKey,void *src,int index)
{
partition_t partition;
semaphore_p();
memcpy((unsigned char *)&partition,(unsigned char *)shmBaseAddr,sizeof(partition));
semaphore_v();
int i;
if(index<=0 || index>partition.sectTable[i].usedNum)
return -1;
for(i=0; i < partition.sectNum; i++)
if( partition.sectTable[i].sectKey == sectKey )
break;
if(i != partition.sectNum)
{
if(partition.sectTable[i].usedNum==partition.sectTable[i].maxNum)
return -1;
else
{
semaphore_p();
memcpy((unsigned char *)(shmBaseAddr+partition.sectTable[i].sectOffset+partition.sectTable[i].dataSize * (index-1)), (unsigned char *)src, partition.sectTable[i].dataSize);
semaphore_v();
partition.sectTable[i].usedNum++;
}
}
semaphore_p();
memcpy((unsigned char *)shmBaseAddr,(unsigned char *)&partition,sizeof(partition));
semaphore_v();
return 1;
}


int shm_reset(int sectKey)
{
semaphore_p();
partition_t partition;
memcpy((unsigned char *)&partition,(unsigned char *)shmBaseAddr,sizeof(partition));
semaphore_v();
int i;
for(i=0; i < partition.sectNum; i++)
if( partition.sectTable[i].sectKey == sectKey )
break;
if(i != partition.sectNum)
{
partition.sectTable[i].usedNum=0;
semaphore_p();
memcpy((unsigned char *)shmBaseAddr,(unsigned char *)&partition,sizeof(partition));
semaphore_v();
return 1;
}
return -1;
}


int shm_get_section_datanum(int sectKey)
{
partition_t partition;
semaphore_p();
memcpy((unsigned char *)&partition,(unsigned char *)shmBaseAddr,sizeof(partition));
semaphore_v();
int i;
for(i=0; i < partition.sectNum; i++)
if( partition.sectTable[i].sectKey == sectKey )
break;
if(i != partition.sectNum)
{
return partition.sectTable[i].usedNum;
}
return -1;
}
### Shared Memory in Programming or System Design Shared memory (SHM) refers to a region of memory that can be accessed by multiple processes simultaneously, allowing them to share data efficiently without requiring explicit inter-process communication mechanisms like pipes or sockets[^1]. In operating systems, shared memory is often implemented through virtual memory techniques where the same physical pages are mapped into the address spaces of different processes. In modern programming languages such as Python and Go, shared memory concepts may not always be directly exposed due to higher-level abstractions. However, they still play critical roles under the hood when dealing with low-level operations involving multiprocessing or multithreading scenarios: #### Implementation Details Across Languages - **Python**: While Python's garbage collector manages object lifecycles automatically, certain libraries provide interfaces for working with shared memory explicitly. For example, `multiprocessing.shared_memory` allows creating blocks of memory accessible across separate process instances[^2]. Example usage: ```python import multiprocessing sm = multiprocessing.shared_memory.SharedMemory(create=True, size=1024) buffer = bytearray(sm.buf) buffer[:] = b'Hello from one process!' # Another process could attach using name 'sm.name' ``` - **Go**: Channels serve as primary tools for safe concurrency but differ fundamentally from traditional SHMs since their purpose revolves around message passing rather than direct pointer sharing between goroutines[^3]. However, both approaches aim at facilitating efficient resource utilization while maintaining synchronization guarantees necessary during concurrent executions. #### Key Characteristics & Considerations When designing software utilizing shared memories consider following aspects carefully: - Synchronization Primitives – Mutexes/Locks must accompany unprotected accesses preventing race conditions. - Data Consistency Models – Sequential consistency vs relaxed ones depending upon use case requirements. - Security Implications – Unauthorized reads/writes pose significant risks necessitating proper isolation measures within kernelspace implementations.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值