Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Menulis kepada mmap memperuntukkan panik hirisan

Menulis kepada mmap memperuntukkan panik hirisan

WBOY
WBOYke hadapan
2024-02-09 09:00:12732semak imbas

写入 mmap 分配的切片会发生恐慌

PHP editor Strawberry akan memperkenalkan kepada anda masalah "panik berlaku apabila menulis kepingan yang diperuntukkan oleh mmap". Apabila menggunakan mmap untuk memperuntukkan memori, jika operasi tulis dilakukan pada masa yang sama, panik peruntukan memori mungkin berlaku. Dalam kes ini, program mungkin mempunyai ralat yang tidak dapat diramalkan atau malah menyebabkan program ranap. Oleh itu, apabila menggunakan mmap untuk memperuntukkan memori, anda perlu memberi perhatian untuk mengelakkan operasi menulis serentak, atau menggunakan kaedah peruntukan memori lain untuk mengelakkan masalah ini. Seterusnya, kami akan menganalisis masalah ini secara terperinci dan menyediakan penyelesaian yang sepadan.

Kandungan soalan

Senario ini adalah untuk menyimpan data penstriman masa nyata ke dalam kawasan dipetakan memori yang disokong fail. Matlamatnya adalah untuk menggunakan mmap untuk menjadikan negeri toleran kesalahan.

Menggunakan mmap dalam aplikasi anda akan mengelakkan bergantung pada kedai nilai kunci Redis.

Berikut adalah prosedurnya:

package main

import (
    "fmt"
    "os"

    "github.com/edsrzf/mmap-go"
)

func main() {
    f, _ := os.OpenFile("./file", os.O_RDWR, 0644)
    defer f.Close()

    mmap, _ := mmap.Map(f, mmap.RDWR, 0)
    defer mmap.Unmap()
    fmt.Println(string(mmap))

    mmap[0] = 'X'
    mmap.Flush()
}
$ go build -gcflags -m=2 -o main cmd/layer/main.go
$ ./main

panic: runtime error: index out of range [0] with length 0

goroutine 1 [running]:
main.main()
        /..//cmd/layer/main.go:21 +0x1d7

Mengapa mmap[0] = 'X' tidak boleh menulis data pada fail? mmap[0] = 'X' 无法将数据写入文件?

解决方法

您的文件是空的,因此您的切片也是空的。您必须首先为文件分配一些字节,然后尝试更改从 mmap.Map()mmap.MapRegion()

Penyelesaian

initFile() 中创建的文件不是人类可读的,您可以制作一个固定大小的字符串,然后将其写入文件,这样您的 memFail anda kosong, oleh itu kepingan anda juga kosong. Anda perlu memperuntukkan beberapa bait pada fail dahulu dan kemudian cuba menukar kepingan yang anda dapat daripada mmap.Map() atau mmap.MapRegion() :

package main

import (
    "os"

    "github.com/edsrzf/mmap-go"
)

var testPath = "./file"

func initFile() {
    size := int64(10 * 1024 * 1024)
    fd, err := os.Create(testPath)
    if err != nil {
        panic("Failed to create output")
    }
    _, err = fd.Seek(size-1, 0)
    if err != nil {
        panic("Failed to seek")
    }
    _, err = fd.Write([]byte{0})
    if err != nil {
        panic("Write failed")
    }
    err = fd.Close()
    if err != nil {
        panic("Failed to close file")
    }
}

func main() {
    f, _ := os.OpenFile("./file", os.O_RDWR, 0644)
    defer f.Close()

    mem, _ := mmap.Map(f, mmap.RDWR, 0)
    defer mem.Unmap()

    mem[0] = 'X'
    mem.Flush()
}
🎜Sila ambil perhatian bahawa kandungan dalam 🎜 menjadi boleh dibaca oleh manusia🎜

Atas ialah kandungan terperinci Menulis kepada mmap memperuntukkan panik hirisan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam