func (l *FileLock) SharedLock() error {
	return syscall.Flock(l.fd, syscall.LOCK_SH)
}
SharedLock takes a co-operative (shared) lock on.
This is idempotent when the Lock already represents a shared lock,
and demotes an exclusive lock to shared atomically.
It will block if an exclusive lock is already held.
package lock
import (
	"errors"
	"syscall"
)
var (
	ErrLocked     = errors.New("file already locked")
	ErrNotExist   = errors.New("file does not exist")
	ErrPermission = errors.New("permission denied")
	ErrNotRegular = errors.New("not a regular file")
)
type FileLock struct {
	path string
	fd   int
}
type LockType int
const (
	Dir LockType = iota
	RegFile
)
func (l *FileLock) TryExclusiveLock() error {
	err := syscall.Flock(l.fd, syscall.LOCK_EX|syscall.LOCK_NB)
	if err == syscall.EWOULDBLOCK {
		err = ErrLocked
	}
	return err
}
func TryExclusiveLock(path string, lockType LockType) (*FileLock, error) {
	l, err := NewLock(path, lockType)
	if err != nil {
		return nil, err
	}
	err = l.TryExclusiveLock()
	if err != nil {
		return nil, err
	}
	return l, err
}
func (l *FileLock) ExclusiveLock() error {
	return syscall.Flock(l.fd, syscall.LOCK_EX)
}
func ExclusiveLock(path string, lockType LockType) (*FileLock, error) {
	l, err := NewLock(path, lockType)
	if err == nil {
		err = l.ExclusiveLock()
	}
	if err != nil {
		return nil, err
	}
	return l, nil
}
func (l *FileLock) TrySharedLock() error {
	err := syscall.Flock(l.fd, syscall.LOCK_SH|syscall.LOCK_NB)
	if err == syscall.EWOULDBLOCK {
		err = ErrLocked
	}
	return err
}
func TrySharedLock(path string, lockType LockType) (*FileLock, error) {
	l, err := NewLock(path, lockType)
	if err != nil {
		return nil, err
	}
	err = l.TrySharedLock()
	if err != nil {
		return nil, err
	}
	return l, nil
}