Информация об изменениях

Сообщение Re[3]: Работа с потоками (threads) в MFC от 30.12.2016 9:39

Изменено 30.12.2016 11:24 Evgeniy Skvortsov

Здравствуйте, RussianFellow, Вы писали:

RF> То есть если я функцию, которая производит вычисления, помечу как static, то её можно сделать потоковой?

Да

RF> И есть ли в этом случае какие-то особенности по работе с такой функцией по сравнению с глобальными потоковыми функциями?


Функция член класса с модификатором static ни чем не отличается от глобальной, кроме того что находится в пространстве имени класса.

Все обычные функции члены класса вызываются со скрытым указателем на экземпляр класса
То есть если есть класс
struct A {
  int m_a;
  void f() {m_a++;}
  static DWORD WINAPI MyThreadFunc(LPVOID lpParam) {return 0;}
};

То при вызове функции f(), на самом деле вызов идёт как f(this) и поэтому внутри функции можно обращаться к переменным, в частности к m_a.
А вот внутри MyThreadFunc — обращаться к m_a уже нельзя. Так как статические функции вызываются так, как они объявлены, this не передаётся.
Но ей передаётся lpParam, поэтому при создании потока можно передать this явно
AfxBeginThread(MyThreadFunc, this)


А в функции потока использовать указатель на экземпляр класса
DWORD WINAPI MyThreadFunc(LPVOID lpParam) {
  A *a = static_cast<A*>(lpParam);
  а-> вызываем что угодно
  return 0;
}


Можно сделать из MyThreadFunc функцию переходник, которая будет звать через указатель нормальную функцию член, в которой можно спокойно работать с данными класса
struct A {
  int m_a;
  void f() {m_a++;}
  static DWORD WINAPI MyThreadFunc(LPVOID lpParam);
  DWORD RealThreadFunc(){};
private:
  static DWORD WINAPI MyThreadFunc(LPVOID lpParam) {return 0;}
};
DWORD WINAPI A::MyThreadFunc(LPVOID lpParam) {
  A *a = static_cast<A*>(lpParam);
  return а->RealThreadFunc();
}


Обрати внимание, статические функции должны определяться с указанием имени класса.
Вкратце так.
Re[3]: Работа с потоками (threads) в MFC
Здравствуйте, RussianFellow, Вы писали:

RF> То есть если я функцию, которая производит вычисления, помечу как static, то её можно сделать потоковой?

Да

RF> И есть ли в этом случае какие-то особенности по работе с такой функцией по сравнению с глобальными потоковыми функциями?


Функция член класса с модификатором static ни чем не отличается от глобальной, кроме того что находится в пространстве имени класса.

Все обычные функции члены класса вызываются со скрытым указателем на экземпляр класса
То есть если есть класс
struct A {
  int m_a;
  void f() {m_a++;}
  static DWORD WINAPI MyThreadFunc(LPVOID lpParam) {return 0;}
};

То при вызове функции f(), на самом деле вызов идёт как f(this) и поэтому внутри функции можно обращаться к переменным, в частности к m_a.
А вот внутри MyThreadFunc — обращаться к m_a уже нельзя. Так как статические функции вызываются так, как они объявлены, this не передаётся.
Но ей передаётся lpParam, поэтому при создании потока можно передать this явно
AfxBeginThread(MyThreadFunc, this)


А в функции потока использовать указатель на экземпляр класса
DWORD WINAPI MyThreadFunc(LPVOID lpParam) {
  A *a = static_cast<A*>(lpParam);
  а-> вызываем что угодно
  return 0;
}


Можно сделать из MyThreadFunc функцию переходник, которая будет звать через указатель нормальную функцию член, в которой можно спокойно работать с данными класса
struct A {
  int m_a;
  void f() {m_a++;}
  static DWORD WINAPI MyThreadFunc(LPVOID lpParam);
  DWORD RealThreadFunc(){};
};
DWORD WINAPI A::MyThreadFunc(LPVOID lpParam) {
  A *a = static_cast<A*>(lpParam);
  return а->RealThreadFunc();
}


Обрати внимание, статические функции должны определяться с указанием имени класса.
Вкратце так.