#include <thread>
#include <iostream>
#include <mutex>
class ThreadLessons {
private:
std::mutex _threading_mutex_in_class;
public:
ThreadLessons() {}
ThreadLessons(const ThreadLessons &tl) {}
ThreadLessons operator=(const ThreadLessons &tl) {return *this;}
void func(std::string s) {
std::unique_lock lg(_threading_mutex_in_class);
std::cout << std::endl;
for(int i{0}; i<10; i++) {
std::cout << s << std::endl;
}
}
};
std::mutex _threading_mutex;
void func(std::string s) {
std::unique_lock lg(_threading_mutex);
std::cout << std::endl;
for(int i{0}; i<10; i++) {
std::cout << s << std::endl;
}
}
int main()
{
std::cout << "Starting threading of function from another class in same file" << std::endl;
ThreadLessons t;
std::thread t1(&ThreadLessons::func, t, "Number 1");
std::thread t2(&ThreadLessons::func, t, "Number 2");
std::thread t3(&ThreadLessons::func, t, "Number 3");
t1.join();
t2.join();
t3.join();
std::cout << "Starting threading of function from main" << std::endl;
std::thread t4(func, "Number 4");
std::thread t5(func, "Number 5");
std::thread t6(func, "Number 6");
t4.join();
t5.join();
t6.join();
return 0;
}
输出:
Starting threading of function from another class in same file
Number 1
Number 1
Number 1
Number 2
Number 2
Number 2
Number 3
Number 3
Number 1Number 2
Number 2
Number 3
Number 3Number 1
Number 2
Number 1Number 3Number 2
Number 2
Number 3
Number 3
Number 1
Number 1
Number 2
Number 1Number 3
Number 2
Number 1
Number 3
Number 3
Starting threading of function from main
Number 4
Number 4
Number 4
Number 4
Number 4
Number 4
Number 4
Number 4
Number 4
Number 4
Number 5
Number 5
Number 5
Number 5
Number 5
Number 5
Number 5
Number 5
Number 5
Number 5
Number 6
Number 6
Number 6
Number 6
Number 6
Number 6
Number 6
Number 6
Number 6
Number 6
当我从ThreadLessons类调用func函数时,如输出中所示,输出到std::cout的1号、2号和3号输出不像使用获取锁的互斥锁时那样具有确定性。
为什么它不适用于类内函数中定义的互斥锁?
已尝试将std::cout用作共享资源,并希望在锁定互斥锁的类的函数内部使用时将其用作共享资源
2条答案
按热度按时间vsmadaxz1#
在C++中,当你传递一个东西给一个函数时,这个对象是***传值的,这实际上意味着这个对象被复制了。
在这里,最终发生的是原始对象的三个副本。每次调用
std::thread
的构造函数都会复制t
,每个线程都有自己的对象和互斥体。因为
std::mutex
是不可复制的,所以在编译之前必须重写复制构造函数,这应该是一个很大的红色提示:正在这里复印。相反,
std::thread
有一个有用的重载,它接受一个指向该对象的指针:t30tvxxf2#
当你把
t
传递给线程构造函数时,会产生一个副本,类的每个示例都有自己的互斥锁,一个互斥锁只被一个线程使用是相当无用的。对于free函数,每次调用该函数都使用同一个互斥锁。
要通过引用传递对象,可以使用
std::ref
:实际上还是做了一个拷贝,但是拷贝是
std::reference_wrapper
的,它 Package 了t
,并且作为一个引用,实际上就好像t
是通过引用传递的一样。