C 中的多线程编程和同步机制使得程序员可以利用计算机的多核心来提高程序的运行效率和性能。本文将介绍多线程编程和同步机制的基本概念和使用方法。
多线程编程基础
在C 中,使用<thread>
库来创建和管理线程。线程可以通过函数、成员函数或者Lambda
表达式来实现。以下是一个使用Lambda
表达式来创建线程的例子:
#include <thread>
#include <iostream>
int main() {
std::thread t([](){
std::cout << "Hello from thread " << std::this_thread::get_id() << std::endl;
});
t.join();
return 0;
}
上述代码创建了一个线程并输出了该线程的ID
。在创建线程时,需要将线程函数作为参数传递给std::thread
。在上述例子中,我们使用了Lambda
表达式来定义线程函数,该表达式会输出一行文本。
同步机制
多线程编程中最常见的问题是数据竞争和死锁。为了避免这些问题,我们需要使用同步机制来控制线程的访问。
互斥量
互斥量是C 中最常用的同步机制之一。互斥量可以保证同一时间只有一个线程可以访问共享资源。以下是一个使用互斥量来保护共享资源的例子:
代码语言:c 复制#include <thread>
#include <mutex>
#include <iostream>
std::mutex mtx;
void thread_func() {
mtx.lock();
std::cout << "Hello from thread " << std::this_thread::get_id() << std::endl;
mtx.unlock();
}
int main() {
std::thread t1(thread_func);
std::thread t2(thread_func);
t1.join();
t2.join();
return 0;
}
上述代码创建了两个线程,并使用互斥量来保护共享资源。在线程函数中,我们先调用mtx.lock()
函数来锁定互斥量,然后访问共享资源,最后再调用mtx.unlock()
函数来释放互斥量。在上述例子中,我们使用了两个线程来访问共享资源,但是只有一个线程可以访问该资源。这是因为在一个线程访问共享资源时,该资源会被锁定,其他线程无法访问该资源,直到该线程释放互斥量为止。
条件变量
条件变量是C 中另一个常用的同步机制。条件变量可以让线程在某些条件满足时才继续执行,否则就等待。以下是一个使用条件变量来同步线程的例子:
代码语言:c 复制#include <thread>
#include <mutex>
#include <condition_variable>
#include <iostream>
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void consumer() {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [](){ return ready; });
std::cout << "Hello from consumer thread " << std::this_thread::get_id() << std::endl;
}
void producer() {
std::this_thread::sleep_for(std::chrono::seconds(1));
ready = true;
cv.notify_one();
}
int main() {
std::thread t1(consumer);
std::thread t2(producer);
t1.join();
t2.join();
return 0;
}
上述代码创建了两个线程,一个生产者线程和一个消费者线程。生产者线程在1秒后将ready
变量设置为true
,然后通知消费者线程继续执行。消费者线程等待条件变量cv
,直到ready
变量的值为true
为止。在该例子中,我们使用了条件变量来同步生产者和消费者线程。
结论
多线程编程和同步机制是C 中非常重要的主题。本文介绍了多线程编程的基本概念和使用方法,以及互斥量和条件变量等常用的同步机制。希望这篇文章对你有所帮助。