c ++ multithreading study notes (0)

More complicated process: the application into separate processes, they run at the same time. As shown, a separate process by conventional inter-process communication channels transmitting the message (signal socket, File, pipes, etc.).

Advantages: 1. The operating system provides an additional communication mechanism attached operations and a higher level of protection between processes, means you can write more secure concurrent code.

           2. You can use a remote connection, run in separate processes on different machines, despite an increase in communication cost, but the number of well-designed system, this may be a low-cost method to improve the availability and performance parallel.

Disadvantages: 1 communication between such processes is usually not set up complicated, is slow, because the operating system will provide some protection between processes, so as not to modify a process to another process data

      2. fixed overhead required to run multiple processes: the time required to start the process, the operating system needs to manage the process of internal resources

Multithreading: run multiple threads in a single process. Thread is lightweight process: each thread run independently, and the threads can run on different instruction sequence. But all the threads in a process share the address space, and most of the data accessed by all threads --- global variable still is global, object reference pointer or the data can be passed between threads.

Pros: This address space were expensive, and the lack of protection of data between threads, so that the recording of the operating system workload is reduced, so the use of multi-threading overhead is much smaller than the use of multiple processes

Disadvantages: flexibility, cost sharing memory: If the data is to be accessed by multiple threads, the programmer must treasure each thread access to data is the same, which means a lot of work needs to be done to communicate between threads

 Concurrent and Parallel:

Parallel pay more attention to performance. In discussing the use of the currently available hardware to improve the speed bulk data processing, we will discuss the parallelism of the program; when the focus is separate task or tasks in response, will discuss the program of concurrency

 

std :: thread learning

Header files need to contain <thread>

Initialize the thread (start the thread)

A simple example:

#include <iostream>
#include <thread>

using namespace std;

void sayHello()
{
    cout << "hello" <<endl;
}

int main()
{
    thread t(sayHello);
    t.join();
}

Initialize the thread (the thread starts) is to construct an instance of std :: thread: std :: thread (func). function func simple means, which is a function application type, the following examples:

#include <iostream>
#include <thread>

using namespace std;

class Test
{
public:
    void operator()()
    {
        cout << "hello" <<endl;
    }
};

int main()
{
    Test test;
    thread t(test);
    t.join();
}

You can also use the class member variables to initialize std :: thread: std :: thread (& Class :: func, (Class) object)

#include <iostream>
#include <thread>

using namespace std;

class Test
{
public:
    void sayHello()
    {
        cout << "hello" <<endl;
    }
};

int main()
{
    Test test;
    thread t(&Test::sayHello, &test);
    t.join();
}

Note: When the function object passed to the thread constructor, the need to avoid the following situations: Variable If you pass a temporary variable instead of a named, c ++ compiler interprets it as a function declaration, rather than the type of object Definition. E.g:

std::thread myThread(func());

Here is equivalent to declare a function called myThread, this function takes one parameter (a pointer to a function with no parameters and returns the function func object), the function returns a std :: thread object, instead of starting a thread.

To solve this problem, the solution:

  • Using multiple sets of parenthesis
std::thread myThread((func()));
  • Use braces
std::thread myThread({func()});
  • Use lambda expressions
std::thread myThread([](){
    do_something();
});

After starting the thread, is a clear need to wait for the end of the thread (join style) or allowed to operate autonomously (separate), if not to make a decision before the object is destroyed, the program will terminate (std :: thread of destructor call std :: terminate ()). Even if there are unusual circumstances but also to ensure the correct thread can join (join) or separated (detached).

If you do not wait for the thread, it is necessary to ensure the effectiveness before the end of the thread, you can access the data. For example the main thread to the child thread pass a reference to a variable A, sub-thread detach, it means that the main thread may end before the child thread, so that variable A will be destroyed, then the child thread and then use A reference will produce abnormal. Conventional methods to deal with this situation: the thread function is complete, copy the data to the thread, not copied to the shared data. If you use an object that can be called as a thread function, this object will be copied to the thread, then the original object will be destroyed immediately, but the object contains pointers and references need to be cautious. Best not to use local variables of a function to create threads. In addition, it is possible to ensure that the end of the thread before the function is done by join () function.

 

Wait for the thread to complete

Using std :: thread method join () to achieve the completion of the waiting thread

Call join () behavior, but also clean up the thread associated storage section, this std::threadobject will no longer have any association with the completion of the thread. This means that only one thread at a time using the join (); Once you have used the join (), std::threadthe object can not be added again when its use joinable (), returns false.

 

Running in the background thread

Using std :: thread method detach () to achieve the completion of the waiting thread

Use detach () thread will run in the background, which means that the main thread does not have a direct interaction with them. In other words, do not wait for the end of the thread; if the thread separation, then there can not be std::threadan object can reference it, separating the thread indeed runs in the background, so separate thread can not be added. But C ++ runtime library to ensure that, when the thread exits, related resources can be recycled properly, ownership and control of a background thread C ++ runtime library will be handled. When the std::threadobject using t.joinable () returns true, it may be used t.detach ()

 

Pass parameters to the thread function

Can be carried out during initialization parameters passed std :: thread myThread (func, arg0, arg1, ...), in addition to use in class member functions to initialize the thread parameters passed std :: thread (& Class :: func, ( Class) object, arg0, arg1, ...)

Here requires attention to two issues:

1. When a pointer to a dynamic variable as a parameter to the thread, you want to rely on implicit conversion function to convert the literal to expect the object (1), but std::threadthe copy constructor will provide a variable, just copy without being converted to a desired type of string literals. The solution is: (2) to convert the incoming first displayed before

void f(int i,std::string const& s);
void oops(int some_param)
{
  char buffer[1024];
  sprintf(buffer, "%i",some_param);
  //std::thread t(f,3,buffer); // 1
  std::thread t(f,3,std::string(buffer));  // 2 使用std::string,避免悬垂指针
  t.detach();
}

2. expected to pass a reference, but the whole object is copied. While it is desirable to pass a parameter type (1) refers to, but std::threadis not aware of the constructor; variable ignoring the copy constructor function parameter type expected, and the blind has been provided.

Solution is to use std :: ref () to convert the parameter to a reference form (2)

void update_data_for_widget(widget_id w,widget_data& data);
void oops_again(widget_id w)
{
  widget_data data;
  //std::thread t(update_data_for_widget,w,data); // 1
  std::thread t(update_data_for_widget,w,std::ref(data)); // 2
  display_status();
  t.join();
  process_widget_data(data);
}

 References:

https://chenxiaowei.gitbook.io/c-concurrency-in-action-second-edition-2019/

Guess you like

Origin www.cnblogs.com/duan-shui-liu/p/11430290.html