C++ C++;从线到线 请考虑此代码: #include <stdio> int myInt = 10; bool firstTime = true; void dothings(){ /*repeatedly check for myInt here*/ while(true) { if(myInt > 200) { /*send an alert to a socket*/} } } void launchThread() { if (firsttime) { std::thread t2(dothings); t2.detach(); firsttime = false; } else { /* update myInt with some value here*/ } return; } int main() { /* sleep for 4 seconds */ while(true) { std::thread t1(launchThread); t1.detach(); } } #包括 int-myInt=10; bool firstTime=true; void dothings(){ /*在此处反复检查myInt*/ while(true){ 如果(myInt>200){/*向套接字发送警报*/} } } void launchThread(){ 如果(第一次){ 标准:螺纹t2(点螺纹); t2.分离(); 第一次=错误; }否则{ /*在此处使用一些值更新myInt*/ } 返回; } int main(){ /*睡4秒钟*/ while(true){ std::线程t1(启动线程); t1.分离(); } }
我必须调用C++ C++;从线到线 请考虑此代码: #include <stdio> int myInt = 10; bool firstTime = true; void dothings(){ /*repeatedly check for myInt here*/ while(true) { if(myInt > 200) { /*send an alert to a socket*/} } } void launchThread() { if (firsttime) { std::thread t2(dothings); t2.detach(); firsttime = false; } else { /* update myInt with some value here*/ } return; } int main() { /* sleep for 4 seconds */ while(true) { std::thread t1(launchThread); t1.detach(); } } #包括 int-myInt=10; bool firstTime=true; void dothings(){ /*在此处反复检查myInt*/ while(true){ 如果(myInt>200){/*向套接字发送警报*/} } } void launchThread(){ 如果(第一次){ 标准:螺纹t2(点螺纹); t2.分离(); 第一次=错误; }否则{ /*在此处使用一些值更新myInt*/ } 返回; } int main(){ /*睡4秒钟*/ while(true){ std::线程t1(启动线程); t1.分离(); } },c++,multithreading,C++,Multithreading,我必须调用launchthread-没有其他方法可以更新值或启动线程t2-这就是第三方SDK的设计方式 请注意,launchThread首先退出。Main将继续循环 但据我所知,dothings()将继续运行 我的问题是-在从main调用launchThread之后,dothings是否仍然可以访问myInt的最新更新值 我在谷歌上找不到一个明确的答案,但我相信会的,但它不是线程安全的,数据损坏可能会发生。但这里的专家可能会纠正我。谢谢。关于myInt和首次 myInt和firstime的生存期
launchthread
-没有其他方法可以更新值或启动线程t2
-这就是第三方SDK的设计方式
请注意,launchThread
首先退出。Main将继续循环
但据我所知,dothings()
将继续运行
我的问题是-在从main调用launchThread
之后,dothings
是否仍然可以访问myInt
的最新更新值
我在谷歌上找不到一个明确的答案,但我相信会的,但它不是线程安全的,数据损坏可能会发生。但这里的专家可能会纠正我。谢谢。关于
myInt
和首次
myInt
和firstime
的生存期将在运行main()
之前开始,在返回main()
之后结束。无论是launchThread
还是doThings
都不会管理任何变量的生存期(除了t2
,它无论如何都是分离的,所以这不重要)
一个线程是由主线程启动的,还是由任何其他线程启动的,都没有任何相关性。一旦一个线程启动,特别是当它被分离时,它基本上是独立的:它与程序中运行的其他线程没有关系
未经同步,您不得访问共享内存
但是,是的,你会遇到问题<代码>myInt
在多个线程之间共享,因此您必须将访问同步到它。如果不这样做,您最终将遇到由于同时访问共享内存而导致的未定义行为。同步myInt
的最简单方法是将其设置为一个
我假设每个给定时间只有一个线程运行launchThread
。但是,看看你的例子,情况可能并非如此。如果不是,您还需要第一次同步
选择
但是,您的myInt
看起来非常像一个。也许您希望在满足条件(myInt>200
)之前阻止doThings
。一个std::condition\u变量将对您有所帮助。这将避免故障,并为处理器节省一些周期。使用某种类型的事件系统也可以帮助您做到这一点,它甚至可以使您的程序更干净、更易于维护
下面是一个使用条件变量和原子来同步线程的小示例。我一直试图保持它的简单,所以这里还有一些改进。我让你自行决定
#include <atomic>
#include <condition_variable>
#include <iostream>
#include <thread>
std::mutex cv_m; // This mutex will be used both for myInt and cv.
std::condition_variable cv;
int myInt = 10; // myInt is already protected by the mutex, so there's not need for it to be an atomic.
std::atomic<bool> firstTime{true}; // firstTime does need to be an atomic, because it may be accessed by multiple threads, and is not protected by a mutex.
void dothings(){
while(true) {
// std::condition_variable only works with std::unique_lock.
std::unique_lock<std::mutex> lock(cv_m);
// This will do the same job of your while(myInt > 200).
// The difference is that it will only check the condition when
// it is notified that the value has changed.
cv.wait(lock, [](){return myInt > 200;});
// Note that the lock is reaquired after waking up from the wait(), so it is safe to read and modify myInt here.
std::cout << "Alert! (" << myInt << ")\n";
myInt -= 40; // I'm making myInt fall out of the range here. Otherwise, we would get multiple alerts after the condition (since it would be now true forever), and it wouldn't be as interesting.
}
}
void launchThread() {
// Both the read and the write to firstTime need to be a single atomic operation.
// Otherwise, two or more threads could read the value as "true", and assume this is the first time entering this function.
if (firstTime.exchange(false)) {
std::thread t2(dothings);
t2.detach();
} else {
{
std::lock_guard<std::mutex> lock(cv_m);
myInt += 50;
}
// Value of myInt has changed. Notify all waiting threads.
cv.notify_all();
}
return;
}
int main() {
for (int i = 0; i < 6; ++i) { // I'm making this a for loop just so I can be sure the program exits
std::thread t1(launchThread);
t1.detach();
}
// We sleep only to wait for anything to be printed. Your program has an infinite loop on main() already, so you don't have this problem.
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
#包括myInt
和第一次的生命周期
myInt
和firstime
的生存期将在运行main()
之前开始,在返回main()
之后结束。无论是launchThread
还是doThings
都不会管理任何变量的生存期(除了t2
,它无论如何都是分离的,所以这不重要)
一个线程是由主线程启动的,还是由任何其他线程启动的,都没有任何相关性。一旦一个线程启动,特别是当它被分离时,它基本上是独立的:它与程序中运行的其他线程没有关系
未经同步,您不得访问共享内存
但是,是的,你会遇到问题<代码>myInt
在多个线程之间共享,因此您必须将访问同步到它。如果不这样做,您最终将遇到由于同时访问共享内存而导致的未定义行为。同步myInt
的最简单方法是将其设置为一个
我假设每个给定时间只有一个线程运行launchThread
。但是,看看你的例子,情况可能并非如此。如果不是,您还需要第一次同步
选择
但是,您的myInt
看起来非常像一个。也许您希望在满足条件(myInt>200
)之前阻止doThings
。一个std::condition\u变量将对您有所帮助。这将避免故障,并为处理器节省一些周期。使用某种类型的事件系统也可以帮助您做到这一点,它甚至可以使您的程序更干净、更易于维护
下面是一个使用条件变量和原子来同步线程的小示例。我一直试图保持它的简单,所以这里还有一些改进。我让你自行决定
#include <atomic>
#include <condition_variable>
#include <iostream>
#include <thread>
std::mutex cv_m; // This mutex will be used both for myInt and cv.
std::condition_variable cv;
int myInt = 10; // myInt is already protected by the mutex, so there's not need for it to be an atomic.
std::atomic<bool> firstTime{true}; // firstTime does need to be an atomic, because it may be accessed by multiple threads, and is not protected by a mutex.
void dothings(){
while(true) {
// std::condition_variable only works with std::unique_lock.
std::unique_lock<std::mutex> lock(cv_m);
// This will do the same job of your while(myInt > 200).
// The difference is that it will only check the condition when
// it is notified that the value has changed.
cv.wait(lock, [](){return myInt > 200;});
// Note that the lock is reaquired after waking up from the wait(), so it is safe to read and modify myInt here.
std::cout << "Alert! (" << myInt << ")\n";
myInt -= 40; // I'm making myInt fall out of the range here. Otherwise, we would get multiple alerts after the condition (since it would be now true forever), and it wouldn't be as interesting.
}
}
void launchThread() {
// Both the read and the write to firstTime need to be a single atomic operation.
// Otherwise, two or more threads could read the value as "true", and assume this is the first time entering this function.
if (firstTime.exchange(false)) {
std::thread t2(dothings);
t2.detach();
} else {
{
std::lock_guard<std::mutex> lock(cv_m);
myInt += 50;
}
// Value of myInt has changed. Notify all waiting threads.
cv.notify_all();
}
return;
}
int main() {
for (int i = 0; i < 6; ++i) { // I'm making this a for loop just so I can be sure the program exits
std::thread t1(launchThread);
t1.detach();
}
// We sleep only to wait for anything to be printed. Your program has an infinite loop on main() already, so you don't have this problem.
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
#包括“我相信它会-但它不是线程安全的,而且可能会发生数据损坏”--是的,这差不多是对它的总结。经验法则:每个线程只能访问它自己的内存,除非你使用同步机制。除此之外,它“可能”起作用,但事实上,它不起作用。@Sean首先,我强烈建议假装detach
不存在。您不可避免地会后悔它在最琐碎的用例之外的使用。@Sean“所有线程都可以访问heap”->它们确实可以,但如果不同步,它将变得一团糟。每个线程在哪里启动其实并不重要。你可能希望看看那篇制作精良的文章:“我相信会的——但它不是线程安全的,数据损坏可能会发生”——是的,这就概括了这一点。