статические функции-члены и безопасность потоков - PullRequest
17 голосов
/ 06 января 2011

Объекты и переменные, созданные в статической функции-члене, не считаются «локальными», как если бы они были в функции-члене, так что теперь они могут совместно использоваться несколькими потоками, верно?

Тогда как, если у вас есть членфункция, которая создает некоторый объект, он будет локальным для потока и поэтому не будет использоваться совместно.

Правильно ли я это сказал?

Ответы [ 4 ]

40 голосов
/ 06 января 2011

Рассмотрим этот класс

class CData
{
public:
    static void func()
    {
        int a;
        static int b;
    }

    int c;
    static int d;
};

int main()
{
    CData::func();
}

Теперь переменная a является локальной для каждого вызова func().Если два потока вызывают func() одновременно, они получают разные версии a.

b является статическим локальным.Значение сохраняется между различными вызовами func().Если два потока вызывают func() одновременно, они обращаются к одной и той же версии b, поэтому им может потребоваться выполнить синхронизацию.

c - переменная экземпляра;он привязан к конкретному экземпляру CData.func() не может получить доступ к c, кроме как с помощью трюка, который я покажу ниже.

d - статическая переменная.Существует один экземпляр d, общий для всех видов использования класса CData, поэтому может потребоваться синхронизация.Его можно легко использовать из статической функции func().

Хитрость, используемая для доступа к данным экземпляра из статической функции, заключается в передаче действительного объекта в функцию.

например,

class CData
{
public:
    static void func(CData *p)
    {
        int a;
        static int b;

        b = p->c;
    }

    int c;
    static int d;
};

int main()
{
    CData data;
    CData::func(&data);
}

Надеюсь, это поможет.

19 голосов
/ 06 января 2011

Нет, вы не правы.

Объекты, созданные в статической функции , не являются общими, и это также относится к любым нормальным функциям.

Объекты могутесли они объявлены как статические сами по себе, и это не зависит от того, является ли функция статической или нет.

void myFunc()
{
    static MyObject o;
    o.CallMethod(); // here o is shared by all threads calling myFunc
}

Когда объект объявляется статическим, это как если бы объект был глобальной переменной,но виден только в области действия функции, в которую он объявлен.

3 голосов
/ 06 января 2011

Нет, вы не правы.И да, C ++ очень сильно злоупотребляет словом «static».

Статическая переменная-член класса, конечно же, глобальная, с классом, действующим как область имен, и с некоторыми различиями в привилегиях доступа, если она частная или защищенная.(доступен только для класса).

Однако статическая функция-член класса аналогична обычной свободной функции (не члену класса) и имеет свои собственные локальные переменные при каждом вызове.

Единственное реальное различие между статической функцией-членом класса и обычной свободной функцией, помимо соглашения об именах, состоит в том, что она имеет доступ к закрытым членам класса (и нуждается во внешнем «экземпляре» одного).

Кроме того, статическая функция-член класса может вызываться из шаблона с переменным параметром шаблона, вызывая то, что обычно называется «полиморфизмом времени компиляции» и обычно используется в метапрограммировании.

Статическая «локальная» переменная в любой функции представляет собой отдельный экземпляр, с другой стороны, также являетсянемного похож на глобальный и чувствителен к проблемам конфликтов потоков, поскольку два потока, вызывающие функцию, обращаются к одному и тому же экземпляру.

1 голос
/ 06 января 2011

Неважно, является ли функция статической или нет (метод класса).Только автоматические переменные могут рассматриваться как local для функции.Если у вас есть адрес этих данных, вы можете получить к нему доступ.

Вы можете использовать, например, локальное хранилище потока , чтобы назначить ваш вывод выделенному контексту потока.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...