C + + Concurrent programming 1-let's start managing multithreaded __linux

Source: Internet
Author: User
Tags assert exception handling

Blog Original: www.freehacker.cn

C++11 in the introduction of multithreaded programming, the general textbooks are not involved in this concept, but in the work of multithreading is essential. This article starts with the simplest Hello World and describes how to create an administrative thread. Hello World

The classic Hello world-style beginnings.

#include <iostream>
#include <thread>

void Hello ()
{
    std::cout << "Hello World" << Std::endl;
}

int main ()
{
    std::thread t (hello);
    T.join (); Without this sentence, will debug error return
    0;
}

This code is very simple, if you use boost multithreaded programming, it should be at the fingertips. First contains the line threading header file <thread>, and then defines a thread object T, which is responsible for managing the thread with the Hello () function as the initial function, and join () waits for the thread function to execute--this is blocked. Creating Threads

The classic Hello World example above uses the most basic thread creation method and is our most common method. The Std::thread object's construction parameters need to be callable object, which can be a function, a function object, a member function of a class, or a lambda expression. Next we'll give the four ways to create threads. take functions as arguments

The Hello C + + concurrency program above is the best example of constructing std::thread with a function as a parameter, no longer repeating here. using function objects as arguments

The function object takes advantage of the invocation overload operator of the C + + class, and the class object that implements the overloaded operator can be invoked as a function. The following example:

#include <iostream>
#include <thread>

class Hello
{public
:
    hello () {}
    void Operator () () const
    {
        std::cout << "Hello World" << Std::endl;
    }
};

int main ()
{
    Hello H;
    Std::thread T1 (h);
    T1.join ();
    return 0;
}

One thing to note here: If you need to pass a temporary function object directly, the C + + compiler resolves the Std::thread object construct to a function declaration:

Std::thread T2 (Hello ()); Error, compile as Std::thread T2 (Hello (*) ()); 
std::thread T3 ((hello ())); OK
std::thread t4{hello ()};//OK
t2.join ();   Compile error:expression must have class type
t3.join ();   OK
t4.join ();   Ok
take a member function of a class as an argument

For the constructor parameters of the Std::thread, the member function name of the class must be unique , and in the following example, if the World1 () and world2 () function names are world, the compilation fails because the name resolution occurs before the parameter matches.

#include <iostream>
#include <thread>
#include <string>

class Hello
{
public :
    hello () {}
    void World1 ()
    {
        std::cout << "Hello World" << Std::endl
    }
    void World2 (std::string text)
    {
        std::cout << "Hello World," << text << Std::endl;
    }
};

int main ()
{
    Hello H;
    Std::thread T1 (&hello::world1, &h);
    Std::thread T2 (&hello::world2, &h, "Lee");
    T1.join ();
    T2.join ();
    return 0;
}
take a Lambda object as an argument
#include <iostream>
#include <thread>
#include <string>

int main ()
{
    std:: Thread T ([] (std::string text) {
        std::cout << "Hello World," << text << Std::endl;
    }, "Lee"); 
  t.join ();
    return 0;
}

When creating a thread object, remember that using a function that can access local variables to create a thread is a bad note. Wait Thread

Join () waits for the thread to complete, only one join () is invoked on one thread object because the behavior of calling join () is responsible for cleaning thread-related content, and if called again, runtime error appears.

Std::thread T ([] () { 
               std::cout << "Hello World" << Std::endl;
});
T.join (); OK
t.join ();//Runtime Error
if (t.joinable ()) 
{
               t.join ();//OK
}

Calls to join () need to select the appropriate invocation time. If the parent thread produces an exception after the thread runs, it is thrown before the join () call, meaning that the call is skipped. The workaround is to use Join () in the absence of an exception-call join () during exception handling.

#include <iostream>
#include <thread>
#include <string>

int main ()
{
    std:: Thread T ([] (std::string text) { 
        std::cout << "Hello World," << text << Std::endl;
    }, "Lee"); 
  try
    {
        throw std::exception ("test");
    }
    catch (std::exception e)
    {
        std::cout << e.what () << Std::endl;
        T.join ();
    }
    if (t.joinable ())
    {
        t.join ();
    }
    return 0;
}

The above is not the fundamental solution to this problem, if other problems caused the program to quit early, the above solution is no solution, the best way is the so-called raii.

#include <iostream> #include <thread> #include <string> class Thread_guard {public:explicit Threa D_guard (Std::thread &_t): t (Std::move (_t)) {if (!t.joinable ()) throw
    Std::logic_error ("No Thread");
        } ~thread_guard () {if (t.joinable ()) {t.join ());
    } thread_guard (Thread_guard const&) = delete;
thread_guard& operator= (thread_guard const &) = delete;
Private:std::thread T;

};  void Func () {Thread_guard Guard (Std::thread ([] (std::string text) {std::cout << "Hello World," <<
    Text << Std::endl;
    }, "Lee");
    try {throw std::exception ("test");
    catch (...)
    {throw;
    int main () {try {func ()};
    catch (Std::exception e) {std::cout << e.what () << Std::endl;
return 0; }
Detach Thread

Detach () separates the child thread from the parent thread. After detaching a thread, you can avoid the exception security problem, even if the thread is still running in the background, the detach can ensure that std::terminate is called when the Std::thread object is destroyed.

The separation thread is usually called a daemon thread (Deamon threads), which is characterized by long running, the thread's lifecycle may start to end from one application, the file system may be monitored in the background, or the cache may be cleaned up or the data structure optimized.

#include <iostream>
#include <thread>
#include <string>
#include <assert.h>

int main ()
{
    std::thread t ([] (std::string text) {
        std::cout << "Hello World," << text << Std::endl;
    } , "Lee");

    if (t.joinable ())
    {
        t.detach ();
    }
    ASSERT (!t.joinable ());

    return 0;
}

The joinable () function is used in the above code, and detach () cannot be used for Std::thread objects that do not have threads, and the joinable () function must be used to determine whether to join or detach. Line Cheng

Normal line Cheng is simple, but remember the following: by default, even if the parameters of our thread function are reference types, the parameters are copied to the thread space and then accessed by the thread execution body. The above thread space is the internal memory that the thread can access. Let's look at the following example:

void f (int i,std::string const& s);
Std::thread T (f,3<

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.