山东鲁中公路建设有限公司网站,wordpress 淘宝客 百度云,wordpress模板 菜谱,石家庄城乡建设局网站6介绍
在多线程编程的世界里#xff0c;协调不同线程之间的工作是一项极具挑战性的任务。线程可能需要等待特定条件的满足#xff0c;或者对共享资源的访问进行限制。C 标准库为我们提供了强大的工具#xff0c;如 std::thread 用于创建和管理线程#xff0c;条件变量用于线…介绍
在多线程编程的世界里协调不同线程之间的工作是一项极具挑战性的任务。线程可能需要等待特定条件的满足或者对共享资源的访问进行限制。C 标准库为我们提供了强大的工具如 std::thread 用于创建和管理线程条件变量用于线程间的同步信号量则用于控制对资源的访问。本文将通过具体的 C 代码示例详细介绍如何使用这些工具。
std::thread 基础
std::thread 是 C11 引入的用于创建和管理线程的类。它允许我们轻松地在程序中创建新的执行线程。下面是一个简单的 std::thread
#include iostream
#include threadvoid printMessage(const std::string message) {std::cout Thread says: message std::endl;
}int main() {std::thread t(printMessage, Hello, World!);t.join();return 0;
}定义了一个函数 printMessage然后使用 std::thread 创建了一个新线程并将 printMessage 函数作为线程的入口点同时传递了一个字符串参数。join() 方法用于等待线程执行完毕。
条件变量
条件变量是一种同步原语用于线程之间的通信和协调。它允许一个线程等待某个条件的满足而另一个线程可以在条件满足时通知等待的线程。 生产者 - 消费者模型示例 生产者 - 消费者模型是多线程编程中常见的模式生产者线程负责生产数据消费者线程负责消费数据。我们可以使用条件变量来实现线程间的同步。
#include iostream
#include queue
#include thread
#include mutex
#include condition_variablestd::queueint dataQueue;
std::mutex mtx;
std::condition_variable cv;
bool isProducing true;// 生产者线程函数
void producer() {for (int i 0; i 5; i) {std::this_thread::sleep_for(std::chrono::seconds(1));{std::unique_lockstd::mutex lock(mtx);dataQueue.push(i);std::cout Produced: i std::endl;}cv.notify_one();}{std::unique_lockstd::mutex lock(mtx);isProducing false;}cv.notify_one();
}//消费者线程函数
void consumer() {while (true) {std::unique_lockstd::mutex lock(mtx);cv.wait(lock, [] { return!dataQueue.empty() ||!isProducing; });if (!dataQueue.empty()) {int value dataQueue.front();dataQueue.pop();std::cout Consumed: value std::endl;} else if (!isProducing) {break;}}
}int main() {std::thread producerThread(producer);std::thread consumerThread(consumer);producerThread.join();consumerThread.join();return 0;
}std::queue dataQueue用于存储生产者生产的数据。 std::mutex mtx用于保护对 dataQueue 的访问确保线程安全。 std::condition_variable cv用于线程间的同步。 producer() 函数生产者线程每隔 1 秒生产一个数据并将其加入队列。生产完成后通知消费者线程。 consumer() 函数消费者线程等待条件变量的通知当队列中有数据时从队列中取出数据进行消费。 cv.wait(lock, [] { return!dataQueue.empty() ||!isProducing; })消费者线程等待直到队列非空或者生产结束。
信号量
信号量是一种用于控制对资源访问的同步原语。在 C 标准库中并没有直接提供信号量的实现可以使用 std::mutex 和 std::condition_variable 来模拟信号量。 信号量的实现
#include mutex
#include condition_variableclass Semaphore {
public:Semaphore(int count 0) : count_(count) {}void notify() {std::unique_lockstd::mutex lock(mtx_);count_;cv_.notify_one();}void wait() {std::unique_lockstd::mutex lock(mtx_);cv_.wait(lock, [this] { return count_ 0; });--count_;}private:int count_;std::mutex mtx_;std::condition_variable cv_;
};#include iostream
#include thread
#include vectorSemaphore sem(2); // 允许最多 2 个线程同时访问资源void accessResource(int id) {sem.wait();std::cout Thread id is accessing the resource. std::endl;std::this_thread::sleep_for(std::chrono::seconds(2));std::cout Thread id has finished accessing the resource. std::endl;sem.notify();
}int main() {std::vectorstd::thread threads;for (int i 0; i 5; i) {threads.emplace_back(accessResource, i);}for (auto t : threads) {t.join();}return 0;
}Semaphore 类实现了一个简单的信号量。notify() 方法用于增加信号量的值并通知等待的线程wait() 方法用于等待信号量的值大于 0 并减少信号量的值。 accessResource() 函数线程在访问资源前调用 sem.wait() 等待信号量访问完成后调用 sem.notify() 释放信号量。 emplace_back 是 C 标准库容器如 std::vector、std::deque 等提供的一个成员函数它主要用于在容器的尾部直接构造一个新元素。
结论
通过 std::thread、条件变量和信号量可以在 C 中实现复杂的多线程程序。条件变量用于线程间的同步确保线程在特定条件满足时才继续执行信号量用于控制对资源的访问避免资源竞争。合理使用这些工具可以提高程序的性能和稳定性。希望本文能帮助你更好地理解和应用这些多线程编程的重要概念。