在VS Code上进行多线程编程demo的debug。
以下面CPP reference中的code为例:
#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex m;
std::condition_variable cv;
std::string data;
bool ready = false;
bool processed = false;
void worker_thread()
{
// 等待直至 main() 发送数据
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, [] {return ready; });
// 等待后,我们占有锁。
std::cout << "Worker thread is processing data\n";
data += " after processing";
// 发送数据回 main()
processed = true;
std::cout << "Worker thread signals data processing completed\n";
// 通知前完成手动解锁,以避免等待线程才被唤醒就阻塞(细节见 notify_one )
lk.unlock();
cv.notify_one();
}
int main()
{
std::thread worker(worker_thread);
data = "Example data";
// 发送数据到 worker 线程
{
std::lock_guard<std::mutex> lk(m);
ready = true;
std::cout << "main() signals data ready for processing\n";
}
cv.notify_one();
// 等候 worker
{
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, [] {return processed; });
}
std::cout << "Back in main(), data = " << data << '\n';
worker.join();
return 0;
}
运行代码,报了下面的错误:
/usr/bin/g++ -fdiagnostics-color=always -g /home/mi/work/tmp/debug/test3.cpp -o /home/mi/work/tmp/debug/test3
/tmp/cco3wOYg.o:在函数‘std::thread::thread<void (&)()>(void (&)())’中:
/usr/include/c++/7/thread:122:对‘pthread_create’未定义的引用
collect2: error: ld returned 1 exit status
原因是没有链接到pthread库文件。
g++ -l参数,会调用到/usr/bin/ld命令,在此基础上,g++命令变为:
/usr/bin/g++ -fdiagnostics-color=always -g /home/mi/work/tmp/debug/test3.cpp -l pthread -o /home/mi/work/tmp/debug/test3
Bash中跑一轮,成功生成目标test3。
g++解决方案:加上-l pthread或者-lpthread
那VS Code中解决方案如何呢?参考Get Started with C++ on Linux in Visual Studio Code
在其项目目录中的.vscode目录下,有一个task.json文件,先看一下默认的配置:
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++ 生成活动文件",
"command": "/usr/bin/g++",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "调试器生成的任务。"
},
{
"type": "cppbuild",
"label": "C/C++: g++-7 生成活动文件",
"command": "/usr/bin/g++-7",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": "build",
"detail": "调试器生成的任务。"
}
],
"version": "2.0.0"
}
在args中的各个字符串和shell中打印的命令行对应上了。
因此,解决此问题,可以将上述的task.json的args改成如下,通过命令行中的空格来分割各个字符串。
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-l",
"pthread",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
// 或者下面的改法
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-lpthread",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
最终的运行效果为:
/usr/bin/g++ -fdiagnostics-color=always -g /home/mi/work/tmp/debug/test3.cpp -l pthread -o /home/mi/work/tmp/debug/test3
生成已成功完成。
最后,我们在return 0的地方,加一个断点,点击debug模式运行。
Breakpoint 1, main () at /home/mi/work/tmp/debug/test3.cpp:33
33 {
Loaded '/lib/x86_64-linux-gnu/libpthread.so.0'. Symbols loaded.
也对应着创建thread的地方。