自己写的共享内存hash链表

本文档提供了C语言实现的共享内存哈希链表的详细定义和操作函数,包括创建、查找、设置和获取键值对,以及链表的内存管理。此外,还包含了单元测试代码用于验证哈希链表的功能。
CAlgHashList.h

#ifndef _C_ALG_HASH_LIST_H_
#define _C_ALG_HASH_LIST_H_
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "CAlgShareList.h"

#ifdef	__cplusplus
extern "C" {
   
   
#endif


typedef struct{
   
   
	unsigned int  k_size;
	unsigned int  v_size;
	unsigned int  max_count;
	unsigned int  trunk_size;
	unsigned int  trunk_mask;
	CAlgShareList free_list;
#ifdef WIN32
#pragma warning(disable:4200)
#endif
	CAlgShareList hlist[0];
#ifdef WIN32
#pragma warning(default:4200)
#endif
}CAlgHashList;

typedef struct{
   
   
	int            pos;
	CAlgShareList  *list;
	CAlgShareNode  *node_base; //node base address
	unsigned char  *kv_base;   //kv base address
	unsigned char  *kv;
}HashListRC;

typedef unsigned int (*Alg_Hash_F)(const void* k, unsigned int size);

static inline unsigned int CAlgHashList_Pow2(unsigned int mask)
{
   
   
	int order = 31;
	while((mask &  (1<< order))== 0 && order > 0)
		order --;

	return 1 << order;
}

static inline unsigned int CAlgHashList_MemSize(unsigned int key_size, unsigned int val_size,
												 unsigned int trunk_size, unsigned int max_count)
{
   
   
	//make trunk_size is pow of 2
	trunk_size = CAlgHashList_Pow2(trunk_size);
	return sizeof(CAlgHashList) 
		+ sizeof(CAlgShareList) * trunk_size
		+ sizeof(CAlgShareNode) * max_count
		+ (key_size + val_size) * max_count;
}

static inline void CAlgHashList_Create(CAlgHashList* h, unsigned int key_size, unsigned int val_size,
									  unsigned int trunk_size, unsigned int max_count)
{
   
   
	unsigned int i;
	CAlgShareNode* n = (CAlgShareNode*)((unsigned char*)(h->hlist) + sizeof(CAlgShareList) * trunk_size);
	trunk_size = CAlgHashList_Pow2(trunk_size);
	h->k_size = key_size;
	h->v_size = val_size;
	h->trunk_size = trunk_size;
	h->max_count = max_count;
	h->trunk_mask = h->trunk_size - 1;
	CAlgShareList_ReSet(&h->free_list, key_size);

	//add ShareNode to free list
	n->curr_data = NULL;
	CAlgShareList_InsertPointer(&h->free_list, NULL, NULL, n, 0);
	for(i=1; i<max_count; i++, n++){
   
   
		(n+1)->curr_data = NULL;
		CAlgShareList_InsertPointer(&h->free_list, 
			n, NULL, n+1, i);
	}

	for(i=0; i<trunk_size; i++){
   
   
		//NOTE: only set key_size, but the list node pointer store key_size + val_size
		CAlgShareList_ReSet(&h->hlist[i], key_size);
	}
}

static inline unsigned int CAlgHashList_DefaultHash(const void* k, unsigned int k_size)
{
   
   
	unsigned int i, hash = 0;
	const unsigned char *p = (const unsigned char *)k;

	for (i = 0; i< k_size; i++, p++) {
   
   
		hash = hash * 33 + *p;
	}
	return hash;
}

static inline int CAlgHashList_Find(CAlgHashList* h, const void* k, HashListRC* rc, 
									  Alg_Cmp_F cmp_f, Alg_Hash_F hash_f)
{
   
   
	CAlgShareList* list;
	CAlgShareNode* node_base = (CAlgShareNode*)(&h->hlist[h->trunk_size]);
	int pos;
	unsigned int hash_v ;
	unsigned char* kv_base = ((unsigned char*)node_base) + sizeof(CAlgShareNode)*h->max_count;
	unsigned int kv_size = h->k_size + h->v_size;

	if
<think>好的,用户问的是如何检测和处理共享内存冲突。首先,我需要回忆一下共享内存相关的知识,尤其是冲突的可能原因和解决方法。根据用户提供的引用内容,特别是引用[3]里的信息,里面有提到同步方法、初始化步骤以及数据结构的设计。 首先,检测共享内存冲突的方法可能包括使用工具检查、同步机制是否完善,以及数据结构的合理性。比如,使用Valgrind的Helgrind工具可以检测线程问题,而tsan能检测数据竞争。另外,在代码层面,需要确保互斥锁的正确使用,比如用pthread的mutex,并且这些锁需要放在共享内存中,并正确初始化。引用[3]提到,共享内存中的mutex和cond需要正确使用,可能还要设置进程共享属性。 处理冲突的方法可能包括优化同步机制,比如减少锁的粒度,使用读锁,或者无锁数据结构。还有在初始化共享内存时,要按照原子操作来创建,避免多个进程同时初始化导致问题。引用[3]里提到的用CREAT | EXCL来创建,失败则直接打开,这样可以保证原子性。初始化时用x位来同步,其他进程轮询检查x位是否复位,确保初始化完成后再操作。 另外,数据结构的设计也很重要,比如使用内存块链表、循环队列等结构,减少冲突的可能性。引用[3]提到可以做成chunk list或者多级hash表,这可能有助于管理共享内存中的数据,避免竞争。 用户可能是在开发多进程应用时遇到了共享内存的问题,比如数据不一致或者程序崩溃。需要排查是否有同步机制缺失,锁是否正确使用,或者初始化过程是否正确。可能需要结合工具检测和代码审查来解决。 总结下来,回答应该分检测和处理两部分,每个部分列出具体的方法,并引用提供的资料作为支持。同时,生成的相关问题可以涉及工具使用、同步机制优化、数据结构设计等,帮助用户进一步学习。</think>### 如何检测和处理共享内存冲突? #### 一、检测共享内存冲突的方法 1. **使用调试工具** - **Valgrind/Helgrind**:检测线程同步问题(如数据竞争、死锁)[^3]。 - **TSan(ThreadSanitizer)**:在编译时加入检测选项(如`-fsanitize=thread`),运行时直接输出数据竞争报告。 - **ipcs/ipcrm**:通过Linux命令`ipcs -m`查看共享内存状态,`ipcrm`删除异常残留的共享内存段[^2]。 2. **代码层同步验证** - **检查互斥锁初始化**:共享内存中的互斥锁需通过`pthread_mutexattr_setpshared`设置为进程间共享属性。 - **原子性操作验证**:确保共享内存创建时使用`shmget`的`IPC_CREAT | IPC_EXCL`标志,避免重复创建[^3]。 3. **状态轮询机制** - 通过`shmctl`的`IPC_STAT`命令检查共享内存的初始化标志位(如x位),确保其他进程在初始化完成后才访问。 --- #### 二、处理共享内存冲突的方法 1. **同步机制优化** - **减少锁粒度**:将大锁拆分为小锁(如分段锁),降低竞争概率。 - **读锁(RWLock)**:对读多少的场景使用`pthread_rwlock`,提升并发性能。 - **无锁数据结构**:如循环队列(Ring Buffer),通过原子操作(CAS)实现高效访问。 2. **共享内存初始化规范** - **原子性创建流程**: ```c shm_id = shmget(key, size, IPC_CREAT | IPC_EXCL | 0666); if (shm_id == -1) { // 已存在则直接打开 shm_id = shmget(key, size, 0666); } ``` - **初始化状态同步**:通过标志位(x位)和轮询机制,确保进程间初始化顺序。 3. **数据结构设计** - **内存块链表(Chunk List)**:将共享内存划分为固定大小的块,通过链表管理空闲块。 - **多级哈希表**:静态预分配结构,避免动态分配引发的竞争。 4. **异常处理** - **信号量超时机制**:在`sem_timedwait`中设置超时,防止死锁。 - **共享内存清理**:进程退出时通过`shmdt`分离内存,主进程负责`shmctl(..., IPC_RMID)`释放资源。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值