web-dev-qa-db-fra.com

Pourquoi cet exemple simple de std :: thread ne fonctionne-t-il pas?

J'ai essayé l'exemple suivant compilé avec g++ -std=gnu++0x t1.cpp et g++ -std=c++0x t1.cpp mais les deux entraînent l'abandon de l'exemple.

$ ./a.out 
terminate called after throwing an instance of 'std::system_error'
  what():  
Aborted

Voici l'exemple:

#include <thread>
#include <iostream>

void doSomeWork( void )
{
    std::cout << "hello from thread..." << std::endl;
    return;
}

int main( int argc, char *argv[] )
{
    std::thread t( doSomeWork );
    t.join();
    return 0;
}

J'essaye ceci sur Ubuntu 11.04:

$ g++ --version
g++ (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2

Quelqu'un sait ce que j'ai manqué?

44
Stéphane

Vous devez joinstd::threads, tout comme vous devez rejoindre pthreads.

int main( int argc, char *argv[] )
{
    std::thread t( doSomeWork );
    t.join();
    return 0;
}

MISE À JOUR: Ce rapport de bogue Debian m'a indiqué la solution: ajoutez -pthread à votre ligne de commande. Il s'agit très probablement d'une solution de contournement jusqu'à ce que le std::thread le code se stabilise et g ++ extrait cette bibliothèque quand elle le devrait (ou toujours, pour C++).

45
rubenvb

Veuillez utiliser la bibliothèque pthread pendant la compilation: g ++ -lpthread.

13
SarB

Code le plus simple pour reproduire cette erreur et comment y remédier:

Mettez ceci dans un fichier appelé s.cpp:

#include <iostream>
#include <stdlib.h>
#include <string>
#include <unistd.h>
#include <thread>
using namespace std;
void task1(std::string msg){
  cout << "task1 says: " << msg;
}
int main(){
    std::thread t1(task1, "hello");
    usleep(1000000);
    t1.detach();
}

Compilez comme ceci:

el@apollo:~/foo7$ g++ -o s s.cpp -std=c++0x

Exécutez-le comme ceci, l'erreur se produit:

el@apollo:~/foo7$ ./s
terminate called after throwing an instance of 'std::system_error'
  what():  Operation not permitted
Aborted (core dumped)

Pour le corriger, compilez-le comme ceci avec le drapeau -pthread:

g++ -o s s.cpp -std=c++0x -pthread
./s

Ensuite, cela fonctionne correctement:

task1 says: hello
3
Eric Leschinski

Pour ce que ça vaut, j'ai eu problème différent avec code similaire en utilisant - threads en g ++ (MinGW). La solution de contournement consistait à mettre un certain "retard" entre la création d'un thread et sa jonction.

Code avec une assertion qui échoue rarement:

std::atomic_bool flag{false};
std::thread worker( [&] () { flag.store(true); } );
worker.join();
assert(flag.load()); // Sometimes fails

Solution de contournement:

std::atomic_bool flag{false};
std::thread worker( [&] () { flag.store(true); } );
while (not flag.load()) { std::this_thread::yield(); }
worker.join();
assert(flag.load()); // Works fine

Notez que yield() seul n'a pas aidé, d'où la boucle while. L'utilisation de sleep_for(...) fonctionne également.

0
Petr Vepřek