lundi 11 février 2019

concurrent access to std::vector (write from one thread read from another)

Given below is a simplified version of code which I am not sure is thread safe.

The main thread pushes back an element into the vector and the background thread tries to access that element by index. The way the code is structured it is gauranteed that the access only happens after the push_back is completed fully.

I wanted to check if the atomic_thread_fence calls will ensure that the concurrent access to the m_appenders vector is safe (even when there is a reallocation). If not what other alternatives can I try (other than using a mutex to gaurd access to the vector).

struct LogMsg {
  size_t id;
}; 
struct FileAppender {
  void write(const LogMsg& msg);
};

std::vector<std::unique_ptr<FileAppender>> m_appenders;
folly::ProducerConsumerQueue<LogMsg> m_queue;

size_t getLogger(std::string name) {
  if (!existsLogger(name)) {
    m_appenders.push_back(make_unique<FileAppender>());
    std::atomic_thread_fence(std::memory_order_release);
    return m_appenders.size();
  } else {
    return id_of_existing_logger;
  }
}

// main thread
void main() {
   auto id = getLogger("main");
   LogMsg msg;
   msg.id = id;
   m_queue.push(msg);
}

// background thread
void writeLoop() {
  while(!stopped) {
    LogMsg msg;
    if (m_queue.pop(msg)) {
        std::atomic_thread_fence(std::memory_order_acquire);     
        m_appenders[msg.id]->write(msg);
    }
  }
}

Aucun commentaire:

Enregistrer un commentaire