网站开发项目需求文档,织梦网站建设,能进外国网站看视频的浏览器,塔式服务器主机建网站在C11之前#xff0c;C并没有提供原生的并发支持。开发者通常需要依赖于操作系统的API#xff08;如Windows的CreateThread或POSIX的pthread_create#xff09;或者第三方库#xff08;如Boost.Thread#xff09;来创建和管理线程。这些方式存在以下几个问题#xff1a; …
在C11之前C并没有提供原生的并发支持。开发者通常需要依赖于操作系统的API如Windows的CreateThread或POSIX的pthread_create或者第三方库如Boost.Thread来创建和管理线程。这些方式存在以下几个问题 平台依赖不同的操作系统提供了不同的线程API这意味着你需要为每个目标平台编写不同的代码或者使用预处理器宏来处理平台差异。这会使代码变得复杂和难以维护。 错误处理困难操作系统的线程API通常通过返回错误码来报告错误这需要你在每次调用API后检查错误码并手动处理错误。这不仅繁琐而且容易出错。 缺乏高级特性操作系统的线程API通常只提供了基础的线程创建和同步功能缺乏一些高级特性如线程池、future和promise等。
相比之下C11的并发库提供了以下优势 平台无关C11的并发库是C标准的一部分这意味着你可以在任何支持C11的编译器上使用它无需考虑平台差异。 异常安全C11的并发库使用异常来报告错误这使得错误处理更加简单和安全。例如如果你试图在已经启动的线程上调用std::thread::joinC11会抛出一个std::system_error异常。 高级特性C11的并发库提供了一些高级特性如std::async、std::future和std::promise等这些特性使得并发编程更加方便和强大。
这些工具使得C程序员可以更方便、更安全地编写多线程代码。下面我们将详细介绍这些并发工具的使用。
1. 线程std::thread
C11的std::thread类提供了对操作系统原生线程的封装。你可以通过创建std::thread对象来创建新的线程并通过成员函数join()或detach()来等待线程结束或让线程在后台运行。
#include iostream
#include threadvoid hello() {std::cout Hello, concurrent world\n;
}int main() {std::thread t(hello);t.join();
}在这个例子中我们创建了一个新的线程来运行hello函数并在主线程中通过join()等待新线程结束。
2. 互斥量std::mutex
C11的std::mutex类提供了对操作系统原生互斥量的封装。你可以使用互斥量来保护共享数据防止多个线程同时访问。
#include mutex
#include threadstd::mutex mtx; // 全局互斥量void print_block(int n, char c) {mtx.lock();for (int i0; in; i) { std::cout c; }std::cout \n;mtx.unlock();
}int main() {std::thread th1(print_block,50,*);std::thread th2(print_block,50,$);th1.join();th2.join();return 0;
}在这个例子中我们使用互斥量mtx来保护std::cout防止两个线程同时输出。
3. 条件变量std::condition_variable
C11的std::condition_variable类提供了对操作系统原生条件变量的封装。你可以使用条件变量来实现线程间的同步。
#include iostream
#include thread
#include mutex
#include condition_variablestd::mutex mtx;
std::condition_variable cv;
bool ready false;void print_id(int id) {std::unique_lockstd::mutex lck(mtx);while (!ready) cv.wait(lck);std::cout thread id \n;
}void go() {std::unique_lockstd::mutex lck(mtx);ready true;cv.notify_all();
}int main() {std::thread threads[10];for (int i0; i10; i)threads[i] std::thread(print_id,i);std::cout 10 threads ready to race...\n;go();for (auto th : threads) th.join();return 0;
}在这个例子中我们使用条件变量cv来实现10个线程的同步。当go函数被调用时所有等待在cv上的线程都会被唤醒。
4. Futurestd::future
C11的std::future类提供了一种表示异步操作结果的方式。你可以使用std::async函数来启动一个异步操作并返回一个std::future对象。然后你可以在任何时候通过std::future::get函数来获取异步操作的结果。
#include iostream
#include futureint factorial(int n) {int res 1;for(int i n; i 1; --i)res * i;return res;
}int main() {std::futureint fut std::async(factorial, 5);std::cout Factorial of 5 is fut.get() std::endl;return 0;
}在这个例子中我们使用std::async启动了一个异步操作来计算5的阶乘并通过std::future::get获取了结果。