2015-01-22 1 views
1

Я использую RWLock для чтения в базе данных mysql, но кажется, что с перерывами следующий код блокирует программы, поскольку он ждет разблокировки?golang sync.RWLock, похоже, создает тупик?

// Returns string value from key in table specified, third parameter should be set to false if it shouldn't be case senstive. 
func (self *DBStore) GetString(table string, key string, vargs...interface{}) (output string) { 

    defer func() { fmt.Println("GETSTRING Freeing Mutex!") }() 
    self.mutex.RLock() 
    fmt.Println("GETSTRING Got Mutex!") 
    defer self.mutex.RUnlock() 

    self.Get(table, key, &output, vargs...) 
    return 

} 

// Retreive a value at key in table specified. 
func (self *DBStore) Get(table string, key string, output interface{}, vargs...interface{}) (found bool) { 

    defer func() { fmt.Println("GET Freeing Mutex!") }() 
    fmt.Println("Requesting Mutex") 
    self.mutex.RLock() 
    fmt.Println("GET Got Mutex!") 
    defer self.mutex.RUnlock() 

Теперь с вышеизложенным, я могу видеть, что я на самом деле не нужно выполнять RLOCK здесь, и я могу просто достаточно просто удалить его, но я был под впечатлением чтения замки не должны мешать другим читать замок. Также кажется, что это прерывисто, и обычно мне приходится несколько раз запускать ту же самую вещь, прежде чем она повторится.

Выход программы:

Requesting Mutex 
GET Got Mutex! 
GET Freeing Mutex! 
GETSTRING Got Mutex! 
Requesting Mutex 

, а затем он просто сидит навсегда заперта. Что мне здесь не хватает?

Любая информация будет оценена!

идти версия go1.4 Darwin/amd64

+0

Отправить процесс А SIGQUIT, чтобы выяснить, где goroutines блокируются. Это может привести к некоторому пониманию того, в чем проблема. –

+1

Предлагаю запустить код с 'go race', чтобы узнать, что происходит. –

+1

Нельзя безопасно приобретать одну и ту же блокировку чтения несколько раз в одном и том же потоке выполнения. –

ответ

1

Подумав о проблеме с спина к спине RLOCK, это имеет смысл.

То, что я не регистрирую здесь, - это блокировки, и теперь ясно, что возникает ситуация, когда Lock находится между спиной к спине RLocks.

В основном замок находится в очереди.

(Thread 1) GetString -> Request Read Lock 
(Thread 1) GetString -> Got Read Lock 
(Thread 2) Set -> Request Write Lock (Blocked, queued.) 
(Thread 1) Get -> Request Read Lock (Blocked, queued.) 

От http://golang.org/src/sync/rwmutex.go?s=862:888#L19

34  if atomic.AddInt32(&rw.readerCount, 1) < 0 { 
35   // A writer is pending, wait for it. 
36   runtime_Semacquire(&rw.readerSem) 
37  } 
Смежные вопросы