Advertisement
k98kurz

Go concurrency slice of pointers of structs with mutexes

Jul 9th, 2023 (edited)
1,186
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 1.62 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.     "fmt"
  5.     "sync"
  6. )
  7.  
  8. type Resource struct {
  9.     data int
  10. }
  11.  
  12. func (r *Resource) increment() {
  13.     r.data++
  14. }
  15.  
  16. type Client struct {
  17.     id       int
  18.     resource Resource
  19.     mu       sync.RWMutex
  20. }
  21.  
  22. type ActiveClients struct {
  23.     clients []*Client
  24.     mu      sync.RWMutex
  25. }
  26.  
  27. func (ac *ActiveClients) add(client *Client) {
  28.     ac.mu.Lock()
  29.     defer ac.mu.Unlock()
  30.     if ac.clients == nil {
  31.         ac.clients = make([]*Client, 0)
  32.     }
  33.     ac.clients = append(ac.clients, client)
  34. }
  35.  
  36. func (ac *ActiveClients) incrementResource(clientId int) {
  37.     ac.mu.RLock()
  38.     defer ac.mu.RUnlock()
  39.     for _, existingClient := range ac.clients {
  40.         if existingClient.id == clientId {
  41.             existingClient.mu.Lock()
  42.             defer existingClient.mu.Unlock()
  43.             existingClient.resource.increment()
  44.             return
  45.         }
  46.     }
  47. }
  48.  
  49. type anError struct {
  50.     errorMsg string
  51. }
  52.  
  53. func (m anError) Error() string {
  54.     return m.errorMsg
  55. }
  56.  
  57. func (ac *ActiveClients) getResource(clientId int) (Resource, error) {
  58.     ac.mu.RLock()
  59.     defer ac.mu.RUnlock()
  60.  
  61.     for _, existingClient := range ac.clients {
  62.         if existingClient.id == clientId {
  63.             existingClient.mu.RLock()
  64.             defer existingClient.mu.RUnlock()
  65.             return existingClient.resource, nil
  66.         }
  67.     }
  68.     return Resource{}, anError{"could not find resource"}
  69. }
  70.  
  71. var wg sync.WaitGroup
  72.  
  73. func main() {
  74.     var users ActiveClients
  75.     users.add(&Client{id: 3})
  76.  
  77.     wg.Add(10)
  78.     for i := 0; i < 10; i++ {
  79.         go func() {
  80.             users.incrementResource(3)
  81.             wg.Done()
  82.         }()
  83.     }
  84.     wg.Wait()
  85.  
  86.     res, err := users.getResource(3)
  87.     if err != nil {
  88.         fmt.Println(err)
  89.     } else {
  90.         fmt.Printf("resource data = %v\n", res.data)
  91.     }
  92. }
  93.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement