Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否将函数放入类中,然后声明;新";确保线程安全? NoOB问题在C++类上。_C++_Multithreading - Fatal编程技术网

是否将函数放入类中,然后声明;新";确保线程安全? NoOB问题在C++类上。

是否将函数放入类中,然后声明;新";确保线程安全? NoOB问题在C++类上。,c++,multithreading,C++,Multithreading,我有一个可以多次调用的函数A,每次调用它时,它都会用函数B创建一个新线程。函数B调用函数C,函数C调用许多Win32 API进行大量处理,所有数据都在函数C的本地 问:将函数C移动到类中并从函数B中将其声明为新函数是否解决了线程安全问题?换句话说,因为fncC()存在于程序内存地址中的同一地址,我担心如果多个函数同时调用它,程序将崩溃 fncA() { _beginthreadex(...fncB) } fncB() { fncC() } fncC() { RegCreateKeyEx(..

我有一个可以多次调用的函数A,每次调用它时,它都会用函数B创建一个新线程。函数B调用函数C,函数C调用许多Win32 API进行大量处理,所有数据都在函数C的本地

问:将函数C移动到类中并从函数B中将其声明为新函数是否解决了线程安全问题?换句话说,因为fncC()存在于程序内存地址中的同一地址,我担心如果多个函数同时调用它,程序将崩溃

fncA()
{
_beginthreadex(...fncB)
}

fncB()
{
fncC()
}

fncC()
{
RegCreateKeyEx(...)
}

它可能是也可能不是,取决于类实际做什么


无论代码是作为独立函数实现的,还是作为类的方法实现的,代码仍然在线程上下文调用它的任何线程中执行。将它放入一个类中,可以将隐藏的
这个
参数引入方法调用中。如果多个线程同时使用同一个类实例,那么仍然需要处理线程并发性问题。另一方面,如果该方法只访问属于该类的数据,并且每个线程都在该类的不同实例上操作,那么这通常是安全的。当多个线程同时访问同一数据/资源时,会出现并发问题。

如果
FncC
仅使用本地数据,并调用线程安全方法,则
FncC
是线程安全的

如果
FncC
甚至调用了单线程不安全的方法,那么
FncC
就不是线程安全的

如果
FncC
在没有适当保护的情况下访问方法范围以外的任何数据,例如静态数据、全局数据、类成员数据,而没有正确使用互斥锁,则
FncC
不是线程安全的


无耻地链接到我之前关于线程安全的回答:

除非类C的成员函数的实现使用自修改代码(不太可能),否则访问程序内存本身不会是问题。您的问题将是访问共享的可变数据和资源

如果我正确理解了这个问题,您是说您将创建一个类“C”的新实例,并从另一个线程专门调用类C的come成员函数

e、 g.伪代码:

void thread1() {
   auto_ptr<C> pc(new C());
   while (1) {
      pc->f();
   }
}
void thread2() {
   auto_ptr<C> pc(new C());
   while (1) {
      pc->f();
   }
}
只有在没有其他线程读取或修改C的'i_'成员的实例时,这才是安全的。在某些情况下,如果只有其他线程读取
i
,这可能是安全的,但前提是您可以保证对
i
的写入是原子的。关于指令顺序和程序中其他地方可能出现的情况,还有更多的警告,因此任何对此类内容的依赖都需要格外小心。在这个人为设计的示例中,没有其他线程会知道'C'的实例,所以这将是很好的

如果C::f()看起来像这样:

void C::f() {
    static int i = 0;
    std::cout << i++ << std::endl;
}
void C::f(){
静态int i=0;

我不知道你是如何声明一些“新的”东西的。线程安全与共享的可变状态有关,而不是线程本身。函数,至少在OO术语中,没有状态(它们经常对它进行操作)。当您有多个线程访问的字段或变量时,应用程序可能不是线程安全的。因此,我不能说您的函数是否是线程安全的,因为我需要知道它们访问的是什么应用程序或对象状态。线程限制是一种有效的多线程策略。如果您的所有状态都真正局限于调用fncC的线程,那么它可能是安全的。为了补充@scottb所说的内容,一分钟也不要认为线程安全只是添加一点语法糖分的问题。因此,如果fncC(TCHAR*sValue)被称为来自多个运行线程的w/o类,那么每个线程都有自己的“副本”吗在函数C中,如果一个线程发送数据“A”,而数据“B”由另一个线程发送,函数C将从“A”开始,然后在处理过程中使用“B”。?每个线程都有自己的堆栈。sValue指针将是fncC中的一个局部变量,但不会复制整个字符串。函数C没有被复制。您似乎混淆了变量,程序指令memoryLocal变量可以被视为只存在于函数的一次运行中。它们要么放在寄存器中,要么放在如果函数同时执行,那么另一个线程将有自己的局部变量
void C::f() {
    static int i = 0;
    std::cout << i++ << std::endl;
}