如何在Golang中读取和写入文件concurent?

时间:2015-03-04 16:25:37

标签: multithreading go webserver mutex

我设置了一个网络服务器,我使用自己的包,在那里我对文件进行写入/读取。当服务器获得tcp连接时,我启动一个不同的goroutine来处理每个连接的请求。在请求处理程序func中,我调用了some_package的func DoSomething()

这是web_server.go的代码:

 package main
 import (
    sp "./some_package"
    "log"
    "net"
    "os"
    "net/http"
   )

func main() {

  l, err := net.Listen("tcp", "0.0.0.0" + ":" + "4567")
  if err != nil {
    log.Println("Error listening:", err.Error())
    os.Exit(1)
  }
  defer l.Close()
  log.Println("Listening on 0.0.0.0:4567")  
  go func() {
    for {
        // Listen for an incoming connection.
        conn, err := l.Accept()
        if err != nil {
            log.Println("Error accepting: ", err.Error())
            os.Exit(1)
        }
        // Handle connections in a new goroutine.
        go handlerFunction(conn)
    }
  }()

  log.Printf("Setting up the Webserver...")
  err = http.ListenAndServe("0.0.0.0:"+"4568", nil)
  if err != nil {
    log.Fatal(err)
  }
}

func handlerFunction(conn net.Conn) {
  defer conn.Close()
  sp.DoSomething()
}

函数DoSomething()读取和写入文件。您可以在包中看到声明它的代码:

package some_package
import (    
    "io/ioutil"
    "strconv"
    "os"
    "log"
   )
func IncrementValue(pastValue string)(newValue string){
  newValueInt, _ := strconv.Atoi(pastValue)
  return strconv.Itoa(newValueInt + 1)
}

func DoSomething() (err error){
  initialValue := "1"
  filename := "myFile.txt"
  if _, err := os.Stat(filename); err == nil {
    someText, err := ioutil.ReadFile(filename)
    if err != nil {
        log.Printf("Error reading")
        return err
    }
    newValue := IncrementValue(string(someText))

    err = ioutil.WriteFile(filename,[]byte(newValue), 0644)
    if err != nil { 
        return err
    }
  }else{
    err = ioutil.WriteFile(filename,[]byte(initialValue), 0644)
    if err != nil { 
        return err
    }
  }
  return
 }

在这种情况下,如何使用mutex.Lockmutex.Unlock之类的锁定机制来对文件进行读取和写入,这样当一个当前正在编写的例程可以阻止另一个例程读取时第一个成功写入文件?

我的示例在阅读或写入文件时是否适合并发?

这是正确的做法吗?谢谢

1 个答案:

答案 0 :(得分:8)

你不能同时读取和写入文件(嗯,这是可能的,但不是你所描述的访问模式)。使用单个互斥锁序列化对文件的所有访问权限:

var fileMutex sync.Mutex

func DoSomething() {
    fileMutex.Lock()
    defer fileMutex.Unlock()

    //...
}