创建结构体func NewRead(readLen uint64) (*Read, error) {
if readLen == 0{
return nil, errors.New("读取长度不能为空")
}
return &Read{Offset:0, ReadLen:readLen}, nil
}
func NewWrite(writeLen uint64)(*Write, error) {
if writeLen == 0{
return nil, errors.New("写入长度不能为空")
}
return &Write{Offset:0, WriteLen:writeLen}, nil
}
func NewFile(F *os.File) (*File, error) {
if F == nil{
return nil, errors.New("F 不能为空")
}
f := &File{File:F}
f.Cond = sync.NewCond(&sync.Mutex{})
return f, nil
}
实现Files接口func (r *Read) Read(file *File) (bytes []byte, err error) {
var (
offset uint64
newOffset uint64
)
bytes = make([]byte, r.ReadLen)
for{
file.Rw.Lock()
fmt.Println("read 获取到读写锁:", os.Getpid())
offset = atomic.LoadUint64(&r.Offset)
newOffset = offset+r.ReadLen
if atomic.CompareAndSwapUint64(&r.Offset, offset, newOffset){
if _, err = file.File.ReadAt(bytes, int64(offset)); err !=nil{
if err != io.EOF{
fmt.Println("read 读取错误:", err)
return
}else {
if atomic.CompareAndSwapUint32(&file.IsEof, 0, 1){
fmt.Println("等待写入1*******************************************************", os.Getpid())
file.Rw.Unlock()
fmt.Println("read 释放读取锁", os.Getpid())
file.Cond.L.Lock()
file.Cond.Wait()
file.Cond.L.Unlock()
fmt.Println("等待写入2*******************************************************")
continue
}
file.Rw.Unlock()
fmt.Println("read 释放读取锁", os.Getpid())
continue
}
}else {
atomic.AddUint64(&r.Rsn, 1)
break
}
}
}
defer func() {
if errs := recover(); errs!=nil{
err = errors.New(fmt.Sprintf("read err :%s", errs))
}
file.Rw.Unlock()
fmt.Println(" defer read 释放读写锁", os.Getpid())
}()
return
}
func (w *Write) Write(file *File, bytes []byte) (err error) {
var(
offset uint64
newOffset uint64
)
for{
file.Rw.Lock()
fmt.Println("write 获取到读取锁")
offset = atomic.LoadUint64(&w.Offset)
newOffset = offset + w.WriteLen
if atomic.CompareAndSwapUint64(&w.Offset, offset, newOffset){
if _, err = file.File.WriteAt(bytes, int64(offset)); err!=nil{
return errors.New(fmt.Sprintf("写入文件错误:%s", err))
}else {
atomic.AddUint64(&w.Wsn, 1)
if atomic.CompareAndSwapUint32(&file.IsEof, 1, 0){
fmt.Println("发送写入信号1************************************")
file.Cond.Signal()
fmt.Println("发送写入信号2****************************************")
}
break
}
}else {
file.Rw.Unlock()
}
}
defer func() {
if errs := recover(); errs!=nil{
err = errors.New(fmt.Sprintf("write err :%s", errs))
}
file.Rw.Unlock()
fmt.Println("write 释放读写锁")
}()
return nil
}