C++ multi-threaded system programming essentials of muduo library learning 03-thread creation and destruction

Dongyang's study notes

Thread creation

The creation of threads is much easier than destruction. You only need to observe the following principles:

  1. Libraries should not create their own "background threads" without prior notification
  2. Try to create threads in the same way, such as muduo::Thread
  3. The thread should not be started before entering the main() function
  4. The creation of threads in the program is best completed in the initialization phase

1. The library should not create its own "background thread" without prior notice

  • Threads are a scarce resource. If the library uses threads secretly, it may lead to overestimation of the available resources of the system.
  • Once there is more than one thread in the program, it is difficult to fork safely, so the library is best not to use threads secretly

2. Try to create threads in the same way, such as muduo::Thread

  • In this way, it is easy to do a unified process in the core destruction phase of the 簿记工作thread. For example, cache the ID of the current thread, and then fetch the thread ID in the future, so you don’t have to fall into the core

请注意: We must consider 野生线程the possibility. Therefore, it must check whether the cached thread id is valid every time, instead of assuming that the id has been cached during the thread startup phase, it just returns the cached value directly.

3. The thread should not be started before entering the main() function

  • Because this breaks the basic assumption of initializing global objects. In case the future code changes cause the thread to access the uninitialized global object, then this kind of obscure error will be very difficult to find. 因此全局对象不能创建线程.

4. The creation of threads in the program is best completed in the initialization phase

  • No more core destruction threads are created during the running of the program, we can easily assign computing tasks and IO tasks to existing threads at a cost of only a fraction of the cost of a newly created thread

Thread destruction

There are several ways to destroy threads:

  • Natural death. Return from the thread main function, the thread exits normally
  • Unusual death. Illegal operations such as throwing exceptions from the main function of the thread or triggering the segfault signal from the thread (usually accompanied by the death of the process. If a thread in the program terminates unexpectedly, I don’t think it is necessary to let the process continue to run with injury)
  • suicide. Call pthread_exit() in the thread to exit the thread immediately
  • He killed. Other threads call pthread_cancel() to forcibly terminate a thread

pthread_cancel 与 C++

  • ****POSIX threads have the concept of cancellation point, **** means that the thread may be terminated (cancel) when it reaches the cancellation point (if other threads call pthread_cancel() on it)

  • The POSIX standard lists functions that must or may be cancellation points

    , The related links are:

    • https://stackoverflow.com/questions/433989/what-are-the-posix-cancellation-points
    • https://pubs.opengroup.org/onlinepubs/000095399/functions/xsh_chap02_09.html#tag_02_09_05_02
  • The difference between C++ and C:

    • In C++, the implementation of cancellation point is different from that of C language. The thread does not terminate immediately after the function is executed, but the function throws an exception.
    • This will give you the opportunity to execute stack unwind (stack unwind) and destruct objects on the stack (especially release the held locks)
    • If you must use the cancellation point, it is recommended to read the short article Cancellation and C++ Exceptions written by Ulrich Drepper (udrepper.livejournal.com/21541.html). But in my opinion, threads should not be killed from the outside

exit(3) is not thread safe in C++

In addition to terminating the process, the exit() function in C++ also deconstructs global objects and static objects of functions that have been constructed. This is potentially 死锁possible

This is actually not the fault of exit(), but the problem of global object destruction:

  • C++ standard没有照顾全局对象在多线程环境下的析构
  • If you really need to actively end the thread, you can consider using the _exit system call. It will not attempt to destruct the global object, but also不会执行其他任何清理工作,比如flush标准输出

In a long-running server, the process can enter a denial of service state, and then it can be killed directly

Guess you like

Origin blog.csdn.net/qq_22473333/article/details/113523357