Защита классов C ++ с помощью pthreads и ссылок

0

Если у меня есть частный член класса, который может быть изменен фоновым потоком и получателем для указанного частного члена, могу ли я использовать ссылку на константу для этого частного члена для получателя или я должен защитить геттер с помощью мьютекса, чтобы обеспечить безопасность? Вот пример кода. Обратите внимание, что я не использую С++ 11, поэтому у меня нет доступа к этим функциям. Я знаю std::atomic и std::lock_guard и их использование, но код, над которым я работаю в данный момент, использует С++ 03.

Стоит отметить, что тип shared_member int больше подходит для простоты

Если есть лучший способ обеспечить безопасность, чем метод get_copyof_shared_int(), я все уши. Однако, если ссылка будет безопасной, которая также будет работать, я только хочу обеспечить безопасность.

#include <pthread.h>

using namespace std;

class testclass{

public:

// return reference to shared_member (provided only as example of ideal getter)

    inline const int& get_shared_member () const{
        return shared_member;
    }

// return copy of shared_member (example of getter known to be thread safe )

    inline const int get_copyof_shared_int () {

        pthread_mutex_lock(&shared_int_mutex);

        int shared_member_copy = shared_member;

        pthread_mutex_unlock(&shared_int_mutex);

        return shared_member_copy;

    }

// initializes shared_member and mutex, starts running background_thread
    void init(int);

private:

    volatile int shared_member; //should be marked volatile because it is used in background_thread()

    pthread_mutex_t shared_int_mutex;

    // thread which may modify shared_member 

    static void *background_thread(void *arg);

};
  • 0
    Вам нужно будет использовать некоторый механизм синхронизации (например, мьютекс), чтобы предотвратить гонку при доступе к данным.
  • 1
    Каждый раз, когда у вас есть переменная, которая может быть прочитана и записана в отдельных потоках выполнения, вы должны обеспечить защиту синхронизации / блокировки независимо от того, является ли рассматриваемая переменная глобальной, членом класса (статическим или нет), переменной стека, динамически распределяется или как угодно ...
Теги:
multithreading
pthreads

2 ответа

1
Лучший ответ

К сожалению, да, технически вы должны защищать геттер, так как операции int не гарантированно являются атомарными.

Что касается геттера, он выглядит так же просто, как и получается, хотя я не уверен, почему у вас есть два разных геттера.

EDIT: не забудьте пометить свою общую переменную как volatile как указано в приведенной выше ссылке. В противном случае оптимизирующий компилятор может сделать некоторые неправильные оптимизации, поскольку он может принять (ошибочно в вашем случае), переменная не будет установлена другим потоком.

  • 0
    Как я пояснил в своем редактировании, первый получатель был бы более идеальным, если бы к shared_member не обращались другие потоки. Спасибо за подсказку о ключевом слове volatile и за ссылку на другой вопрос! Это действительно сводится к сути.
1

Взятие ссылки на это по существу подобно передаче указателя (ссылки обычно реализуются как контрактный слой над указателями).

Это означает, что нет никакой гарантии, что ваш поток не будет считывать значение в какое-то неудобное время, например, когда другой поток на другом ядре находится в середине написания.

Кроме того, вы можете посмотреть в С++ 1 а также заголовки.

Я бы также посоветовал не встраивать геттер с мьютексом.

const int get_copyof_shared_int () {

    std::lock_guard<std::mutex> lock(shared_int_mutex);

    return shared_int;

}
  • 0
    +1 за особенности C ++ 11. std::atomic<int> может быть использован для этой ситуации. Да, я изменил свой вопрос, потому что код, над которым я работаю, - это C ++ 03, поэтому нет std :: lock_guard или std :: atomic. но оба отлично подходят для тех, у кого есть возможность использовать C ++ 11! Кроме того, я благодарен за критику в отношении включения геттера мьютексом, поскольку я не на 100% понимаю, когда и когда не следует использовать встроенный метод, есть ли у вас более подробный ответ относительно того, почему не совсем лучший способ встроить мою вторую (тема -безопасно) добытчик?
  • 0
    Встраивание: по большей части, не: пусть решит компилятор. Вам нужно начинать оптимизацию, только если вы выполнили профилирование, которое говорит вам, что компилятор выбирает плохо, или если вы создаете сложный кусок кода, который вы действительно уверены, что вы хотите, чтобы компилятор всегда выдавал встроенный код вместо того, чтобы использовать функцию для ,
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню