下面的代码编译并按预期工作.结构(类)A来源于std::thread并扩展了int更多.该main代码创建了一些线程,并随后等待他们完成.
问题是虽然代码在struct中没有析构函数的情况下进行编译A,但是当析构函数被取消注释时(~A(){})我得到:
错误:使用已删除的函数'std :: thread :: thread(const std :: thread&)'
而且我不知道为什么.
此外,我不明白为什么代码可以同时使用push_back和emplace_back同时根据我的理解它不应该使用push_back.
#include <iostream>
#include <thread>
#include <vector>
struct A : std::thread {
int i;
A(void f(const char*),const char* s,int i_) : std::thread{f,s},i{i_}{
std::cout<<"A created"<<std::endl;
}
//~A(){} // uncomment to see error
};
void dosomething(const char* s){
std::cout<<s<<std::endl;
}
int main(){
std::vector<A> aa;
aa.emplace_back(&dosomething,"hi people",3434);
aa.push_back(A(&dosomething,"hi again people",777));
aa.emplace_back(&dosomething,"hi again …Run Code Online (Sandbox Code Playgroud) 我知道,在某些情况下,您可以避免使用锁定互斥锁(std::mutex)std::atomic,从而提高性能.
你能说出这样的情况,并且最好显示一些关于如何做到这一点的示例代码(你如何使用std::atomic)?
此外,当我锁定互斥锁时,性能会下降,因为其他线程在互斥锁被锁定的一段时间内无法继续工作.这是互斥锁的唯一问题吗?我的意思是,锁定/解锁互斥锁是一项昂贵的操作,还是仅仅是我上面提到的?
我在对我看来完全有效的代码上遇到了段错误。
这是一个最小的重新创建示例:
#include <iostream>
#include <thread>
void func()
{
/* do nothing; thread contents are irrelevant */
}
int main()
{
for (unsigned idx = 0; idx < 1000; idx++)
{
std::thread t(func);
void* buffer = malloc(1000);
free(buffer);
t.join();
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我进行了打印,以检查哪个迭代失败;我在第292次迭代中遇到了细分错误。
我使用了gcc-linaro-4.9.4(从这里获取:https ://releases.linaro.org/components/toolchain/binaries/4.9-2017.01/arm-linux-gnueabihf/ )。
我这样编译程序:
arm-linux-gnueabihf-g++ -std=c++11 -std=gnu++11 -lpthread -pthread main.cpp -o main.out
Run Code Online (Sandbox Code Playgroud)
我尝试在gcc-linaro-6.5中重新创建它,但那里没有问题。
知道为什么会这样吗?
编译此代码时没有警告/错误。
在strace下运行它并没有什么特别的。
在GDB下运行它可以发现分段错误发生在free函数中:
Thread 1 "main.out" received signal SIGSEGV, Segmentation fault.
_int_free (av=0x76d84794 <main_arena>, p=0x1e8bf, have_lock=0) at malloc.c:4043 …Run Code Online (Sandbox Code Playgroud) [更新:]我现在正在生成多个进程并且它运行得相当好,尽管基本的线程问题仍然存在.[/]
我正在尝试编写一个编译一堆opencl内核的c ++(g ++ 4.6.1)程序.大部分时间都花在clBuildProgram中.(这是遗传编程,实际运行代码和评估适应性要快得多.)我正在尝试编译这些内核的编译,到目前为止没有任何运气.此时,线程之间没有共享数据(除了拥有相同的平台和设备引用),但它一次只能运行一个线程.我可以将这个代码作为几个进程运行(只需在linux中的不同终端窗口中启动它们),然后它将使用多个内核但不在一个进程内.我可以使用具有相同基本线程代码(std :: thread)的多个核心,只需要基本数学,所以我认为这与opencl编译或我忘记的一些静态数据有关.:) 有任何想法吗?我已经尽力使这个线程安全,所以我很难过.
我正在使用AMD的SDK(opencl 1.1,大约6/13/2010)和5830或5850来运行它.SDK和g ++并不像它们那样是最新的.我最后一次安装一个较新的Linux发行版以获得更新的g ++,我的代码以半速运行(至少是opencl编译),所以我回去了.(刚刚检查了该安装上的代码,它仍以半速运行,没有线程差异.)另外,当我说它一次只运行一个线程时,它将启动所有这些线程,然后在两个线程之间交替,直到它们完成,然后执行接下来的两个等等.看起来所有的线程都在运行,直到代码构建程序.我没有在clBuildProgram中使用回调函数.我意识到这里可能会出现很多错误,如果没有代码,很难说.:)
我很确定这个问题发生在clBuildProgram的内部或调用中.我正在打印这里的时间,推迟的线程会在第一次编译时返回很长的编译时间.这些clBuildProgram调用之间唯一的共享数据是设备ID,因为每个线程的cl_device_id具有相同的值.
这是我启动线程的方式:
for (a = 0; a < num_threads; a++) {
threads[a] = std::thread(std::ref(programs[a]));
threads[a].detach();
sleep(1); // giving the opencl init f()s time to complete
}
Run Code Online (Sandbox Code Playgroud)
这是它陷入困境的地方(这些都是传递的局部变量,尽管设备ID将是相同的):
clBuildProgram(program, 1, & device, options, NULL, NULL);
Run Code Online (Sandbox Code Playgroud)
每个线程是否具有唯一上下文或command_queue似乎没有区别.我真的怀疑这是问题,这就是为什么我提到它.:)
更新:使用fork()生成子进程将适用于此.
编译以下代码时
#include <iostream>
#include <vector>
#include <thread>
#include <chrono>
#include <mutex>
std::mutex cout_mut;
void task()
{
for(int i=0; i<10; i++)
{
double d=0.0;
for(size_t cnt=0; cnt<200000000; cnt++) d += 1.23456;
std::lock_guard<std::mutex> lg(cout_mut);
std::cout << d << "(Help)" << std::endl;
// std::cout << "(Help)" << d << std::endl;
}
}
int main()
{
std::vector<std::thread> all_t(std::thread::hardware_concurrency());
auto t_begin = std::chrono::high_resolution_clock::now();
for(auto& t : all_t) t = std::thread{task};
for(auto& t : all_t) t.join();
auto t_end = std::chrono::high_resolution_clock::now();
std::cout << "Took : " << …Run Code Online (Sandbox Code Playgroud) 我正在运行Ubuntu 14.04.
我重现的步骤:
创建一个新的C++项目(New - > C++ - > Hello World项目),我调用了它 TestStdThread
将主文件中的代码更改为:
#include <thread>
#include <iostream>
int main() {
std::cout << "You have " << std::thread::hardware_concurrency() << " cores." << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)转到TestStdThread - >属性 - > C/C++构建 - >设置 - > GCC C++编译器,并将命令选项从更改g++为g++ -std=c++11
转到TestStdThread - >属性- > C/C++编译- >设置- > GCC C++编译器- >包括添加/usr/include到包含路径(-I) ,并添加pthread.h到包含文件(-include)
转到TestStdThread - > Properties - > C/C++ Build - > …
#include<iostream>
#include<thread>
using namespace std;
void f1(double& ret) {
ret=5.;
}
int main() {
double ret=0.;
thread t1(f1, ret);
t1.join();
cout << "ret=" << ret << endl;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码无法编译,并出现以下错误消息:
g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
In file included from /usr/local/include/c++/5.3.0/thread:39:0,
from main.cpp:2:
/usr/local/include/c++/5.3.0/functional: In instantiation of 'struct std::_Bind_simple<void (*(double))(double&)>':
/usr/local/include/c++/5.3.0/thread:137:59: required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(double&); _Args = {double&}]'
main.cpp:11:21: required from here
/usr/local/include/c++/5.3.0/functional:1505:61: error: no type named 'type' in 'class …Run Code Online (Sandbox Code Playgroud) 我见过大多数使用std::mutex互斥体是全局的例子.我想知道为什么这样做有什么具体的原因?我有自己的程序,我不这样做,只是将互斥量作为一个std::thread std::ref.拥有全局变量不是不好的做法,std::mutexes如果没有语言限制理由这样做,那么C++中全局背后的理性是什么?
我最近发现了一个使用std::thread和的奇怪行为dlopen.
基本上,当我std::thread在一个使用dlopen我收到sigsev 的库中执行a时.库本身与pthread链接,pthread是调用的可执行文件dlopen.
一旦我链接可执行文件pthread或库本身一切正常.但是,我们使用的是基于插件的基础架构,我们不知道应用程序本身是否与pthread相关联.因此,不能将可执行文件始终链接到pthread.
请附上一些代码来重现问题.目前我不确定导致该问题的原因.这是gcc,glibc,libstdc ++还是ld.so的问题?有没有一种方便的方法来解决这个问题?我看起来这个glibc bug是相关的,但我使用的是glibc2.27(debian测试).
pthread_create从图书馆打电话似乎很有效.
#include <thread>
#include <iostream>
void thread()
{
std::thread t ([](){std::cout << "hello world" << std::endl;});
t.join();
}
extern "C" {
void hello()
{
thread();
}
}
Run Code Online (Sandbox Code Playgroud)
#include <iostream>
#include <dlfcn.h>
/** code from https://www.tldp.org/HOWTO/html_single/C++-dlopen/
*/
int main() {
std::cout << "C++ dlopen demo\n\n";
// open the library
std::cout << "Opening hello.so...\n";
void* handle = dlopen("./libhello.so", …Run Code Online (Sandbox Code Playgroud) 我刚刚得到了一个有趣的比赛条件。考虑以下类:
#include <atomic>
#include <chrono>
#include <iostream>
#include <thread>
class A
{
std::thread th;
std::atomic_bool stop = false;
public:
A() = default;
A(const A &) = delete;
A &operator=(const A &) = delete;
~A()
{
stop.store(true);
th.join();
}
virtual void Step() = 0;
void Start()
{
th = std::thread([this]
{
while (true)
{
if (stop.load())
return;
// Just to help reproduce the race condition.
std::this_thread::sleep_for(std::chrono::milliseconds(50));
Step();
}
});
}
};
struct B : A
{
void Step() override
{
std::cout …Run Code Online (Sandbox Code Playgroud)