Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapa program Go saya ranap kerana "terlalu banyak fail terbuka"?

Mengapa program Go saya ranap kerana "terlalu banyak fail terbuka"?

WBOY
WBOYasal
2023-06-10 16:15:08918semak imbas

Go ialah bahasa pengaturcaraan yang sangat popular, terutamanya dalam bidang pembangunan bahagian belakang. Walau bagaimanapun, kadangkala akan berlaku masalah "terlalu banyak fail terbuka" yang menyebabkan program ranap.

Pertama, mari kita fahami apa itu "terlalu banyak fail terbuka". Dalam program, sistem pengendalian akan memperuntukkan bilangan deskriptor fail yang terhad (pendek kata fd) kepada program, yang boleh difahami sebagai pengecam fail terbuka. Apabila program membuka fail, ia akan menduduki fd, dan apabila program menutup fail, fd akan dikeluarkan. Proses ini sangat biasa, contohnya, deskriptor fail digunakan dalam operasi seperti membaca dan menulis fail, membuat sambungan rangkaian, dsb.

Walau bagaimanapun, masalahnya ialah deskriptor fail yang diperuntukkan oleh sistem kepada program adalah terhad. Had khusus bergantung pada sistem pengendalian dan perkakasan Apabila bilangan fail yang dibuka oleh program melebihi had yang diberikan oleh sistem, ralat "terlalu banyak fail terbuka" akan berlaku. Ralat ini akan menyebabkan program ranap atau mempunyai hasil lain yang tidak dapat diramalkan.

Seterusnya, mari kita lihat cara untuk mengelakkan masalah ini.

Cara pertama ialah menggunakan pernyataan dengan. Kenyataan ini terdapat dalam banyak bahasa, seperti kata kunci dengan dalam Python. Dalam Go, kita boleh menggunakan kata kunci tangguh untuk mencapai fungsi yang serupa. Idea teras kaedah ini adalah untuk menutup fail sejurus selepas program selesai menggunakannya untuk melepaskan deskriptor fail. Berikut ialah contoh:

func main() {
    file, err := os.Open("example.txt")
    if err != nil {
        log.Fatal(err)
    }
    defer file.Close()

    // Do something with the file
}

Dalam kod di atas, kami membuka fail menggunakan fungsi Buka daripada pakej os dan menutup fail menggunakan kata kunci tangguh di hujung blok kod.

Kaedah kedua ialah melaraskan had sistem. Dalam sistem Linux, kita boleh menggunakan perintah ulimit untuk melaraskan bilangan deskriptor fail yang diperuntukkan kepada program oleh sistem. Kita boleh memasukkan arahan berikut dalam terminal untuk melihat had semasa:

$ ulimit -n

Jika output ialah 1024, maka had semasa ialah 1024 deskriptor fail. Kita boleh melaraskan had ini kepada nilai yang lebih besar menggunakan perintah berikut:

$ ulimit -n 65535

Arahan ini melaraskan had semasa kepada 65535 deskriptor fail. Sila ambil perhatian bahawa kaedah ini hanya boleh digunakan dalam keadaan khas, kerana ia boleh menyebabkan ranap sistem atau hasil lain yang tidak dapat diramalkan.

Kaedah ketiga ialah menggunakan "File Pool". Kumpulan fail ialah struktur data yang direka khusus untuk mengurus deskriptor fail, memberikan pembangun kawalan yang lebih besar ke atas bilangan dan penggunaan deskriptor fail. Berikut ialah pelaksanaan kumpulan fail asas (sila ambil perhatian bahawa pelaksanaan ini adalah untuk demonstrasi sahaja dan mungkin mengandungi pepijat):

type filePool struct {
    files   []*os.File
    max     int
    current int
}

func newFilePool(max int) *filePool {
    return &filePool{
        files:   make([]*os.File, max),
        max:     max,
        current: 0,
    }
}

func (fp *filePool) GetFile(filename string) (*os.File, error) {
    var file *os.File
    if fp.current == fp.max {
        return nil, errors.New("filePool full")
    }

    for _, f := range fp.files {
        if f != nil && f.Name() == filename {
            return f, nil
        }
    }

    file, err := os.Open(filename)
    if err != nil {
        return nil, err
    }

    fp.files[fp.current] = file
    fp.current++

    return file, nil
}

func (fp *filePool) Close() error {
    for _, f := range fp.files {
        if f != nil {
            f.Close()
        }
    }

    return nil
}

Dalam kod di atas, kami mentakrifkan struktur FilePool, yang termasuk fail (penerangan fail) senarai, nombor had maksimum, dan nombor yang sedang digunakan. Kaedah GetFile digunakan untuk mendapatkan fail Jika melebihi had maksimum, ia akan mengembalikan nol dan ralat jika tidak, ia akan menyemak sama ada fail telah dibuka, ia akan mengembalikan fail yang telah dibuka; fail baharu dan menambahkannya ke dalam senarai. Kaedah tutup digunakan untuk menutup semua fail.

Di atas ialah tiga cara untuk mengelakkan ralat "terlalu banyak fail terbuka". Menggunakan pernyataan dengan dan pengumpulan fail adalah kedua-dua cara yang berkesan untuk mengurus bilangan deskriptor fail, manakala melaraskan had sistem ialah pilihan terakhir. Dalam perkembangan sebenar, kita harus menggunakan dua kaedah pertama sebaik mungkin dan elakkan menggunakan kaedah ketiga.

Atas ialah kandungan terperinci Mengapa program Go saya ranap kerana "terlalu banyak fail terbuka"?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn