[Go] 解决go的fatal error: concurrent map writes map非并发安全

map不是并发安全的 , 当有多个并发的groutine读写同一个map时 

会出现panic错误

concurrent map writes

例如下面的代码会出现这个错误:

var mMap map[int]int

func TestMyMap(t *testing.T) {
    mMap = make(map[int]int)

    for i := 0; i < 5000; i++ {
        go func() {
            mMap[i] = i
        }()
        go readMap(i)
    }
}
func readMap(i int) int {
    return mMap[i]
}

解决这个错误可以有多种方式 , 现在采取读写锁的方式 ,

并发访问map是不安全的,会出现未定义行为,导致程序退出。所以如果希望在多协程中并发访问map,必须提供某种同步机制,一般情况下通过读写锁sync.RWMutex实现对map的并发访问控制,将map和sync.RWMutex封装一下,可以实现对map的安全并发访问

改造后的代码

type SMap struct {
    sync.RWMutex
    Map map[int]int
}

func (l *SMap) readMap(key int) (int, bool) {
    l.RLock()
    value, ok := l.Map[key]
    l.RUnlock()
    return value, ok
}

func (l *SMap) writeMap(key int, value int) {
    l.Lock()
    l.Map[key] = value
    l.Unlock()
}

var mMap *SMap

func TestMyMap(t *testing.T) {
    mMap = &SMap{
        Map: make(map[int]int),
    }

    for i := 0; i < 5000; i++ {
        go func() {
            mMap.writeMap(i, i)
        }()
        go readMap(i)
    }
}
func readMap(i int) (int, bool) {
    return mMap.readMap(i)
}

 有这三种方式:

1.使用channel
2.使用sync.map
3.使用map但必须进行加锁

<think>好的,我现在遇到了一个编译错误,提示说在scripts/selinux/gemheaders/genheaders中出现了致命错误:classmap.h没有那个文件或目录。我需要先弄清楚这个问题的原因,然后找到解决办法。 首先,我应该考虑这个错误的可能原因。通常,这种“没有那个文件或目录”的错误在编译过程中很常见,可能的原因包括缺少依赖的头文件、路径配置错误或者编译步骤不正确。这里提到的是classmap.h文件缺失,所以首先需要确认这个文件是否应该存在于项目中,或者是否需要生成。 接下来,我需要了解genheaders工具的作用。genheaders可能是一个用于生成头文件的脚本,属于SELinux的一部分。SELinux相关的代码通常位于Linux内核的安全模块中,或者可能在用户空间的工具链里。如果这个工具是内核编译的一部分,那么可能是内核源代码的配置或编译步骤出了问题。 接下来,我应该检查以下几点: 1. **检查文件是否存在**:首先在源代码目录中搜索classmap.h文件。可以使用find命令或者locate来查找。如果文件不存在,可能需要生成它,或者确认是否安装相应的开发包。 2. **依赖关系**:确认是否安装了所有必要的开发依赖包。例如,在基于Debian的系统上,可能需要安装libselinux-dev或者类似的包。有时候头文件会被放在这些开发包中。 3. **编译顺序**:如果classmap.h是由其他工具生成的,可能需要先执行某个生成步骤。比如,在编译内核或某些项目时,需要先生成一些头文件,然后才能继续编译。检查Makefile或者编译文档,看是否有生成头文件的步骤被遗漏了。 4. **路径配置**:确认编译时的包含路径是否正确。可能classmap.h位于某个标准路径,而编译器没有包含该路径。需要检查编译命令中的-I参数是否包含了正确的目录。 5. **版本问题**:可能当前的代码版本与系统环境不兼容。比如,代码可能需要特定版本的库或工具链,而当前安装的版本过旧或有冲突。 然后,我可以尝试以下步骤来解决这个问题: - **更新源代码**:如果是通过版本控制系统获取的代码,确保代码是最新的,可能这个问题已经在后续提交中修复了。 - **检查文档或README**:查看项目中的文档,是否有关于生成classmap.h的说明,或者需要安装的依赖项。 - **手动生成classmap.h**:如果项目中有脚本或工具可以生成这个头文件,尝试运行相关的生成命令。可能需要执行make的一些特定目标,比如make headers或者类似的。 - **安装缺失的开发包**:使用包管理器搜索classmap.h相关的包,安装对应的开发包。例如,在Ubuntu中,可以运行apt-file search classmap.h来查找哪个包提供该文件,然后安装它。 如果在尝试上述步骤后问题仍然存在,可能需要更深入地查看编译日志,确定生成classmap.h的具体步骤,或者向社区寻求帮助,查看是否有其他人遇到类似的问题。 此外,还可以检查项目的构建系统配置,比如autoconf或CMake生成的配置是否正确,是否检测到了所有必要的依赖项。有时候配置过程中的错误会导致某些头文件无法正确生成或包含。 总结来说,解决这个问题的关键在于确定classmap.h的来源,确保生成该文件的步骤被执行,或者安装包含该文件的必要软件包。可能需要结合项目的具体构建流程和系统环境来调整解决方案。</think>遇到编译错误`scripts/selinux/genheaders/genheaders: fatal error: classmap.h: 没有那个文件或目录`,通常由以下原因导致: --- ### **逐步排查与解决方案** #### **1. 确认文件是否存在** - **执行命令**:在源代码目录中搜索`classmap.h`: ```bash find /path/to/source -name "classmap.h" ``` 若文件不存在,说明需要生成或安装依赖。 --- #### **2. 检查依赖项** - **安装SELinux开发包**: ```bash # Debian/Ubuntu sudo apt-get install libselinux-dev # RHEL/CentOS sudo yum install libselinux-devel ``` 该包通常包含SELinux相关头文件。 --- #### **3. 生成缺失的头文件** - **定位生成脚本**: - `genheaders`脚本的作用是根据策略生成头文件(如`classmap.h`)。 - 需确保先执行策略编译步骤。 - **手动生成步骤**: 1. 进入SELinux策略目录(通常为`security/selinux`或`scripts/selinux`)。 2. 执行策略编译命令: ```bash make -C scripts/selinux genheaders ``` 3. 重新编译主项目。 --- #### **4. 检查编译路径** - **确认包含路径**: - 确保编译命令包含`-I`参数指向`classmap.h`所在目录。 - 例如,若头文件在`security/selinux/include`,添加: ```bash CFLAGS += -Isecurity/selinux/include ``` --- #### **5. 验证代码完整性** - **更新代码仓库**: ```bash git pull # 若使用Git ``` 确保没有因代码版本过旧导致的文件缺失。 --- ### **总结** 1. 安装`libselinux-dev`或`libselinux-devel`。 2. 手动执行策略编译生成`classmap.h`。 3. 检查编译路径是否包含头文件位置。 4. 若问题持续,检查项目文档或提交Issue。 通过以上步骤,应能解决`classmap.h`缺失导致的编译错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值