You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MIT6.824 Lab1-MapReduce任务计数测试失败与ioutil.ReadDir重复文件问题

问题解决:WSL2下MIT6.824 Lab1 Job Count测试重复文件条目问题

问题背景

在WSL2 Ubuntu环境完成MIT6.824 Lab1-MapReduce实验时,其他测试全部通过,但任务计数测试(job count test)失败,输出如下:

*** Starting job count test.
--- map jobs ran incorrect number of times (10 != 8)
--- job count test: FAIL

排查发现:实际仅生成8个mr-worker-jobcount-*文件,但jobcount.go的Reduce函数调用ioutil.ReadDir(".")返回了重复的文件条目。

相关代码片段:

jobcount.go 原Map/Reduce函数

func Map(filename string, contents string) []mr.KeyValue {
    me := os.Getpid()
    f := fmt.Sprintf("mr-worker-jobcount-%d-%d", me, count)
    count++
    err := ioutil.WriteFile(f, []byte("x"), 0666)
    if err != nil {
        panic(err)
    }
    time.Sleep(time.Duration(2000+rand.Intn(3000)) * time.Millisecond)
    return []mr.KeyValue{mr.KeyValue{"a", "x"}}
}

func Reduce(key string, values []string) string {
    files, err := ioutil.ReadDir(".")
    if err != nil {
        panic(err)
    }
    invocations := 0
    for _, f := range files {
            invocations++
    }
    return strconv.Itoa(invocations)
}

测试脚本片段

echo '***' Starting job count test.

rm -f mr-*

$TIMEOUT ../mrcoordinator ../pg*txt &
sleep 1

$TIMEOUT ../mrworker ../../mrapps/jobcount.so &
$TIMEOUT ../mrworker ../../mrapps/jobcount.so
$TIMEOUT ../mrworker ../../mrapps/jobcount.so &
$TIMEOUT ../mrworker ../../mrapps/jobcount.so

NT=`cat mr-out* | awk '{print $2}'`
if [ "$NT" -eq "8" ]
then
  echo '---' job count test: PASS
else
  echo '---' map jobs ran incorrect number of times "($NT != 8)"
  echo '---' job count test: FAIL
  failed_any=1
fi

wait

重复文件条目的成因

核心原因是WSL2的跨系统文件系统挂载机制:

  1. 当实验目录位于Windows挂载目录(如/mnt/c)时,WSL2通过9P协议访问NTFS文件系统,该协议在并发文件操作场景下,目录遍历可能出现缓存不一致或重复枚举的问题。
  2. Map任务是并发执行的,多个worker同时创建mr-worker-jobcount-*文件,Reduce任务读取目录时,9P协议的目录缓存未及时同步,导致ioutil.ReadDir返回重复的文件条目。
  3. ioutil.ReadDir底层依赖系统调用readdir,在非原生Linux文件系统(如NTFS通过9P挂载)中,该调用的实现可能存在竞态条件,导致重复返回同一目录项。

不修改jobcount.go的解决方案

方案1:将实验目录迁移到WSL2原生文件系统

把Lab1的代码和测试文件放在WSL2内部的ext4文件系统中(如/home/your-username/6.824),而非Windows挂载目录。原生Linux文件系统不会有9P协议的兼容性问题,ioutil.ReadDir会正确返回唯一的目录条目。

方案2:调整WSL2文件系统挂载参数

修改WSL2的挂载配置,减少缓存不一致的概率:

  1. 在WSL2中创建/etc/wsl.conf文件(若不存在)。
  2. 添加以下内容:
    [automount]
    options = "metadata,umask=0022,case=off,noatime"
    mountFsTab = false
    
  3. 关闭WSL2(在Windows命令行执行wsl --shutdown),重新启动WSL2。该配置会优化9P协议的挂载参数,降低目录缓存不一致的概率。

方案3:确保Reduce任务在所有Map任务完成后执行

检查你的coordinator实现,确认是否严格遵循MapReduce流程:所有Map任务完成后才触发Reduce任务。若coordinator提前触发Reduce,可能导致Reduce在Map文件创建过程中读取目录,从而遇到未同步的文件条目。不过此方案仅适用于coordinator流程存在瑕疵的情况,若其他测试已通过,优先级低于前两个方案。

内容的提问来源于stack exchange,提问作者Aj002Th

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 21:10:38