STL学习笔记(五)——温习一下C++的一些重要概念(下)

温习一下C++的一些重要概念(下)

关于命名空间与头文件的概念,相信你对此已经理解得很深刻了,在此不再赘述(可翻阅《C++ Primer Plus》的相关章节)。我们来重点回顾一下以下知识点:
  • 差错和异常处理
  • 可被调用的对象
  • 并发与多线程
  • 初识分配器
本节我们主要学习可被调用的对象、并发与多线程、初识分配器。

2.可被调用的对象

C++中可被某种方式调用其某些函数的对象可以是:
  • 函数
  • 指向成员函数的指针
  • 函数对象
  • lambda,严格地说它是一种函数对象
void func(int x, int y);
auto obj = [](int x, int y){};
class C
{
public:
	void operator() (int x, int y) const;
	void memfunc(int x, int y) const;
}
int main()
{
	C c;
	std::shared_ptr sp(new C);
	
	// bind()使用可被调用的对象【绑定】命令参数.
	std::bind(func, 11, 22)();            // 调用func(11, 22);
	std::bind(obj, 11, 22)();             // 调用obj(11, 22);
	std::bind(C(), 11, 22)();             // 调用C::operator()(11, 22);
	std::bind(&C::memfunc, c, 11, 22)();  // 调用c.memfunc(11, 22);
	std::bind(&C::memfunc, sp, 11, 22)(); // 调用sp->memfunc(11, 22);
	
	// async()使用可被调用的对象【启动】任务.
	std::async(func, 11, 22);             // 执行func(11, 22);
	std::async(obj, 11, 22);              // 执行obj(11, 22);
	std::async(c, 11, 22);                // 执行c.operator()(11, 22);
	std::async(&C::memfunc, &c, 11, 22);  // 执行c.memfunc(11, 22);
	std::async(&C::memfunc, sp, 11, 22);  // 执行sp->memfunc(11, 22);
}
std::bind()和std::async()在后面的章节中会深入地学习。一般的,如果想声明可被调用的对象,可使用类模板std::function<>。

3.并发与多线程

在c++11之前,语言本身和c++标准库都不支持并发,当然,C语言和Windows API均提供了一组多线程操作的函数。在C++11中,不论内核语言或标准库都加强支持并发编程。
#include 
#include     // C++11新增

std::thread::id main_thread_id = std::this_thread::get_id();

void hello()  
{
    std::cout << "Hello Concurrent World\n";
    if (main_thread_id == std::this_thread::get_id())
        std::cout << "This is the main thread.\n";
    else
        std::cout << "This is not the main thread.\n";
}

void pause_thread(int n) {
    std::this_thread::sleep_for(std::chrono::seconds(n));
    std::cout << "pause of " << n << " seconds ended\n";
}

int main() {
    std::thread t(hello);
    std::cout << t.hardware_concurrency() << std::endl;//可以并发执行多少个(不准确)
    std::cout << "native_handle " << t.native_handle() << std::endl;//可以并发执行多少个(不准确)
    t.join();
    std::thread a(hello);
    a.detach();
    std::thread threads[5];                         // 默认构造线程

    std::cout << "Spawning 5 threads...\n";
    for (int i = 0; i < 5; ++i)
        threads[i] = std::thread(pause_thread, i + 1);   // move-assign threads
    std::cout << "Done spawning threads. Now waiting for them to join:\n";
    for (auto &thread : threads)
        thread.join();
    std::cout << "All threads joined!\n";
}

4.初识分配器

c++标准库在许多地方采用特殊对象处理内存的分配和归还,这种特殊对象称为“分配器”(可简单理解为一个内存管理器)。
最初,分配器作为STL的一部分而引入,用来处理不同类型指针(例如near/far/huge指针);现在则作为一种内存模型,使得共享内存、垃圾回收、面向对象数据库等解决方案能够保持一致接口。
c++标准库中定义的默认分配器如下:
namespace std
{
	template 
	class allocator;
}
该默认分配器可在分配器得以被当做实参使用的任何地方充当默认值,它会执行内存分配和回收的一般方法:调用new和delete操作符。但是c++对于调用这些操作符的时间未作明确规定,因此,默认分配器甚至可对其内部所得内存采用缓存机制。
绝大多数程序都使用默认分配器,只有少数情况下才需要自行写一个分配器。在后面的章节我们会详细地探讨分配器,及其接口。

<完>

你可能感兴趣的:(STL/Boost,STL,多线程,分配器)