2015-10-13 4 views
7

मान लें कि फ़ाइल Foo.txt फ़ाइल की सामग्री निम्नानुसार है।गोलांग में फ़ाइल पढ़ने पर मैं फाइल सिस्टम कैश को कैसे छोड़ूं?

Foo Bar Bar Foo 

निम्नलिखित लघु कार्यक्रम पर विचार करें।

package main 

import "syscall" 
import "fmt" 


func main() { 
    fd, err := syscall.Open("Foo.txt", syscall.O_RDONLY, 0) 
    if err != nil { 
     fmt.Println("Failed on open: ", err) 
    } 
    data := make([]byte, 100) 
    _, err = syscall.Read(fd, data) 
    if err != nil { 
     fmt.Println("Failed on read: ", err) 
    } 
    syscall.Close(fd) 
} 

जब हम कार्यक्रम ऊपर चलाते हैं, हम जो सही व्यवहार है कोई त्रुटि हो,।

अब, मैं निम्नलिखित होने के लिए syscall.Open लाइन को संशोधित करता हूं।

fd, err := syscall.Open("Foo.txt", syscall.O_RDONLY | syscall.O_SYNC | syscall.O_DIRECT, 0) 

जब मैं प्रोग्राम को फिर से चलाता हूं, तो मुझे निम्न (अवांछनीय) आउटपुट मिलता है।

Failed on read: invalid argument 

कैसे मैं सही ढंग से झंडे syscall.O_SYNC और syscall.O_DIRECT के रूप में फाइल सिस्टम कैश लंघन के लिए open man page द्वारा निर्दिष्ट पारित कर सकते हैं?

ध्यान दें कि मैं syscall फ़ाइल इंटरफ़ेस का उपयोग कर रहा सीधे os फ़ाइल इंटरफेस के बजाय क्योंकि मैं os द्वारा प्रदान कार्यों में उन झंडे पारित करने के लिए एक तरह से नहीं मिल सकता है, लेकिन मैं समाधान है कि os प्रदान की है कि उपयोग करने के लिए खुला रहा हूँ वे पढ़ने पर फाइल सिस्टम कैश को अक्षम करने के लिए सही तरीके से काम करते हैं।

ध्यान दें कि मैं Ubuntu 14.04 पर ext4 पर अपने फाइल सिस्टम के रूप में चल रहा हूं।


अद्यतन: मैं नीचे दिए गए कोड में @Nick क्रेग-लकड़ी के पैकेज का उपयोग करने की कोशिश की।

package main 

import "io" 
import "github.com/ncw/directio" 
import "os" 
import "fmt" 


func main() { 
    in, err := directio.OpenFile("Foo.txt", os.O_RDONLY, 0666) 
    if err != nil { 
     fmt.Println("Error on open: ", err) 
    } 

    block := directio.AlignedBlock(directio.BlockSize) 
    _, err = io.ReadFull(in, block) 
    if err != nil { 
     fmt.Println("Error on read: ", err) 
    } 
} 

उत्पादन निम्नलिखित

Error on read: unexpected EOF 
+1

आप खुले-पढ़ने के करीबी लोगों के साथ सटीक करने की कोशिश की है जाने से कुछ और में तर्क (सी शायद)? मैं मैन पेज पर जो देख सकता हूं, उससे O_SYNC केवल लेखन कार्यों को प्रभावित करता है और O_DIRECT को उपयोगकर्ता स्पेस में किसी प्रकार का सटीक आकार (?) बफर चाहिए, यह एक विशिष्ट समस्या हो सकती है, लेकिन मैं पहले उस काम को प्राप्त करने का प्रयास करूंगा सी में ... – mrd0ll4r

+0

@ mrd0ll4r, असल में मैंने [इस कार्यक्रम] भाग लिया (http://man7.org/tlpi/code/online/book/filebuff/direct_read.c.html) और उसी त्रुटि को 'EINVAL' मिला सी पक्ष। तो नहीं, यह विशिष्ट नहीं है। – merlin2011

उत्तर

1
open आदमी पृष्ठ से

है, नोट के तहत:

लिये O_DIRECT फ्लैग लंबाई और उपयोगकर्ता के स्थान का पता पर संरेखण प्रतिबंध लगा सकते हैं बफर और फ़ाइल ऑफसेट I/Os। लिनक्स संरेखण प्रतिबंधों में फ़ाइल सिस्टम और कर्नेल संस्करण से भिन्नता है और पूरी तरह से अनुपस्थित हो सकता है।

तो आपके पास मेमोरी या फ़ाइल ऑफसेट के संरेखण के मुद्दे हो सकते हैं, या आपका बफर आकार "गलत" हो सकता है। संरेखण और आकार क्या होना चाहिए स्पष्ट नहीं है। मैन पेज जारी है:

हालांकि वर्तमान में किसी फ़ाइल या फ़ाइल सिस्टम के लिए इन प्रतिबंधों को खोजने के लिए किसी फ़ाइल के लिए कोई फ़ाइल सिस्टम-स्वतंत्र इंटरफ़ेस नहीं है।

और यहां तक ​​कि लीनुस में वजन का होता है, हमेशा की तरह महत्व ढंग से:

"बात यह है कि हमेशा किया है मुझे O_DIRECT के बारे में परेशान है कि पूरे इंटरफेस सिर्फ बेवकूफ है, और शायद एक विक्षिप्त द्वारा डिजाइन किया गया है कुछ गंभीर दिमागी-नियंत्रित पदार्थों पर बंदर। " -Linus

शुभकामनाएं!

पेज। अंधेरे में स्टैब: 512 बाइट क्यों नहीं पढ़ते?

+0

O_DIRECT का उपयोग करने की जटिलताओं पर बहुत ही रोचक अंतर्दृष्टि। क्या आप गो में फाइल सिस्टम कैश छोड़ने के सवाल के किसी भी समाधान से अवगत हैं (भले ही इसमें एक पूरी तरह से अलग मार्ग शामिल हो)? मुझे समाधान की भी आवश्यकता है। – vastlysuperiorman

5

आप मेरे directio package का आनंद ले सकते हैं जिसे मैंने वास्तव में इस उद्देश्य के लिए बनाया है।

साइट

यह जाओ भाषा (OpenBSD और plan9 को छोड़कर) जाओ के सभी समर्थित OSes के तहत प्रत्यक्ष आईओ के उपयोग को सक्षम करने के लिए पुस्तकालय है से

डायरेक्ट आईओ ओएस में डेटा को बफर किए बिना डिस्क से और आईओ करता है। यह उपयोगी होता है जब आप बहुत सारे डेटा को पढ़ रहे हैं या लिख ​​रहे हैं जिन्हें आप ओएस कैश को भरना नहीं चाहते हैं।

पैकेज डॉक्स

http://go.pkgdoc.org/github.com/ncw/directio

+0

मैंने आपके पैकेज का उपयोग करने का प्रयास किया लेकिन जब मैं पढ़ने की कोशिश करता हूं तो मुझे 'अप्रत्याशित ईओएफ' मिलता है। आपके उदाहरण में – merlin2011

+0

@ merlin2011 '' Foo.txt "' 'directio.BlockSize' से बड़ा है? –

+0

यह 'directio.BlockSize' से छोटा है। – merlin2011

0

आप fadvice और madvice उपयोग करने के लिए कोशिश कर सकते हैं के लिए यहाँ देखें, लेकिन कोई गारंटी नहीं है। दोनों बड़ी फ़ाइलों/डेटा के साथ अधिक काम करेंगे, क्योंकि:

आंशिक पृष्ठ जानबूझकर उम्मीद पर संरक्षित हैं कि अनियंत्रित स्मृति को छोड़ने के लिए आवश्यक स्मृति को संरक्षित करना बेहतर है।

लिनक्स स्रोत कोड देखें, कुछ क्या करेगा और क्या नहीं। उदाहरण के लिए POSIX_FADV_NOREUSE कुछ भी नहीं करता है।

http://lxr.free-electrons.com/source/mm/fadvise.c#L62

http://lxr.free-electrons.com/source/mm/madvise.c

package main 

import "fmt" 
import "os" 
import "syscall" 

import "golang.org/x/sys/unix" 

func main() { 
    advise := false 
    if len(os.Args) > 1 && os.Args[1] == "-x" { 
     fmt.Println("setting file advise") 
     advise =true 
    } 

    data := make([]byte, 100) 
    handler, err := os.Open("Foo.txt") 
    if err != nil { 
     fmt.Println("Failed on open: ", err) 
    }; defer handler.Close() 

    if advise { 
     unix.Fadvise(int(handler.Fd()), 0, 0, 4) // 4 == POSIX_FADV_DONTNEED 
    } 

    read, err := handler.Read(data) 
    if err != nil { 
     fmt.Println("Failed on read: ", err) 
     os.Exit(1) 
    } 

    if advise { 
     syscall.Madvise(data, 4) // 4 == MADV_DONTNEED 
    } 

    fmt.Printf("read %v bytes\n", read) 
} 

/usr/bin/समय -v ./direct -x

Command being timed: "./direct -x" 
User time (seconds): 0.00 
System time (seconds): 0.00 
Percent of CPU this job got: 0% 
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.03 
Average shared text size (kbytes): 0 
Average unshared data size (kbytes): 0 
Average stack size (kbytes): 0 
Average total size (kbytes): 0 
Maximum resident set size (kbytes): 1832 
Average resident set size (kbytes): 0 
Major (requiring I/O) page faults: 2 
Minor (reclaiming a frame) page faults: 149 
Voluntary context switches: 2 
Involuntary context switches: 2 
Swaps: 0 
File system inputs: 200 
File system outputs: 0 
Socket messages sent: 0 
Socket messages received: 0 
Signals delivered: 0 
Page size (bytes): 4096 
Exit status: 0 
संबंधित मुद्दे