With the continuous improvement of computer hardware, more and more software are beginning to use multi-threading technology to improve program performance and response speed. C language is a language that supports multi-threaded programming. This article will introduce some multi-threaded programming techniques in C.
Before doing multi-threaded programming, we need to understand what a thread is. A thread is the smallest unit of program execution. It has its own program counter, register set and stack, and shares the code segment, data segment and resources of the process. Multithreaded programming allows us to execute multiple threads at the same time, and these threads can execute concurrently.
In multi-threaded programming, multiple threads may access the same shared resource at the same time. This can lead to data inconsistency, so we need to use a mutex to protect shared resources. A mutex is a synchronization primitive that allows multiple threads to share the same resource, but only one thread can access the resource. The C standard library provides the std::mutex class to support the mutex lock mechanism.
For example, we can use the following code snippet to protect the read and write operations of a variable:
#include <mutex> #include <iostream> std::mutex mtx; // 申明一个互斥锁 int main() { int count = 0; std::thread t1([&count]() { for (int i = 0; i < 1000000; i++) { mtx.lock(); // 加锁 count++; mtx.unlock(); // 解锁 } }); std::thread t2([&count]() { for (int i = 0; i < 1000000; i++) { mtx.lock(); // 加锁 count++; mtx.unlock(); // 解锁 } }); t1.join(); t2.join(); std::cout << "count: " << count << std::endl; return 0; }
In the above code, we protect count by creating a std::mutex object mtx Read and write operations on variables. Use the mtx.lock() function to lock the mtx object and prohibit other threads from accessing the count variable. Using the mtx.unlock() function can unlock the mtx object and allow other threads to access the count variable.
In multi-threaded programming, sometimes we need to wait for certain conditions to be met before continuing execution. In this case, you can use a condition variable to wait for and notify other threads.
Condition variables are a synchronization mechanism that allow threads to wait for specific events instead of busy waiting. When a thread waits for a condition variable, it goes to sleep until another thread notifies it via the condition variable. The C standard library provides the std::condition_variable class to support the condition variable mechanism.
For example, we can use the following code snippet to wait and notify threads:
#include <condition_variable> #include <mutex> #include <thread> #include <iostream> std::mutex mtx; std::condition_variable cv; bool is_ready = false; void work() { std::unique_lock<std::mutex> lock(mtx); cv.wait(lock, [] { return is_ready; }); // 等待条件变量满足 std::cout << "Work started!" << std::endl; } int main() { std::thread t(work); std::this_thread::sleep_for(std::chrono::seconds(2)); { std::lock_guard<std::mutex> lock(mtx); is_ready = true; } cv.notify_one(); // 通知工作线程条件变量 t.join(); return 0; }
In the above code, we create a worker thread t and use std::unique_lock
In multi-threaded programming, multiple threads usually modify the same variable at the same time. In this case, we need to ensure that the operation on the variable is atomic. The C standard library provides the std::atomic type to support atomic operations.
std::atomic type can guarantee that the operation is atomic, that is, it ensures that a set of operations will not be interrupted by other threads under any circumstances. Use the std::atomic class to avoid race conditions and other multi-threading related problems.
For example, we can use the following code snippet to demonstrate the use of std::atomic:
#include <iostream> #include <atomic> #include <thread> std::atomic<int> counter(0); // 申明一个原子性变量 void func() { for (int i = 0; i < 1000000; ++i) { counter++; // 自增操作 } } int main() { std::thread t1(func); std::thread t2(func); t1.join(); t2.join(); std::cout << "counter: " << counter << std::endl; return 0; }
In the above code, we create two threads t1 and t2, and use std: Counter variable of type :atomic
Summary
This article introduces some multi-threaded programming techniques in C. Using mutexes and condition variables can protect shared resources and implement thread communication, while using std::atomic can guarantee atomic operations and avoid multi-threading related problems. When using multi-threaded programming, please pay attention to thread safety and correctness, and ensure that operations on shared resources are atomic.
The above is the detailed content of Multi-threaded programming skills in C++. For more information, please follow other related articles on the PHP Chinese website!