摘要:进程间通信:管道 在两个进程间发送消息的非常简单的方法:使用信号。我们创建通知事件,通过它引起响应,但传送的信息只限于一个信号值。 这里介绍管道,通过它进程之间可以交换更加有用的数据。 popen与pcolse 最简单的在两个程序之间传递数据的方法就是使用popen和pclose函数 #includ
阅读全文
摘要:ipc状态命令 大多数Linux系统都提供了一组命令,用于从命令行上访问IPC信息以及清理游离的IPC机制。他们是ipcs和ipcrm命令。 IPC机制一个令人烦恼的问题是:编写错误的程序或因为某些原因而执行失败的程序将把它的IPC资源(如消息队列中的数据)遗留在系统中,这将导致对程序的新调用执行失
阅读全文
摘要:非类的成员函数以及成员变量 inline修饰的函数或变量(c++17开始可以修饰变量)在全局保留一份; static修饰的函数或者变量会在各自的编译单元都保留一份; static函数的局部static变量也会有多份,inline函数的static变量只有一份; static inline 修饰的函数
阅读全文
摘要:为什么要使用并发编程? 在本世纪初之前,大部分开发人员不常需要关心并发编程;用到的时候,也多半只是在单处理器上执行一些后台任务而已。只有少数为昂贵的工作站或服务器进行开发的程序员,才会需要为并发性能而烦恼。原因无他,程序员们享受着摩尔定律带来的免费性能提升,而高速的 Intel 单 CPU 是性价比
阅读全文
摘要:std::future C11 中增加的线程类,使得我们能够非常方便的创建和使用线程,但有时会有些不方便,比如需要获取线程返回的结果,就不能通过 join() 得到结果,只能通过一些额外手段获得,比如:定义一个全局变量,在子线程中赋值,在主线程中读这个变量的值,整个过程比较繁琐。C 提供的线程库中提
阅读全文
摘要:目的 读出类似这样的配置文件 abc:abc 并且对文件进行一个简单的加密操作 注意的点 配置信息结构体key和value要自己设定,这不是在python中 对于C语言中动态内存分配记得要提供“一个返回有效行数的函数” config.h #include <stdio.h> #include <st
阅读全文
摘要:对齐模数的查看和修改 #pragma pack(show) 我们加入这样一条预编译指令,进行编译后即可查看当前的对齐模数 warning C4810: 杂注 pack(show) 的值 == 8 #pragma pack(4) 我们也可以执行这样的一条指令来修改当前的对齐模数 结构体内存对齐规则 从
阅读全文
摘要:C++11 提供了一个原子类型 std::atomic,通过这个原子类型管理的内部变量就可以称之为原子变量,我们可以给原子类型指定 bool、char、int、long、指针等类型作为模板参数(不支持浮点类型和复合类型)。 由于原子操作是通过指令提供的支持,因此它的性能相比锁和消息传递会好很多。**
阅读全文
摘要:条件变量是 C11 提供的另外一种用于等待的同步机制,它能阻塞一个或多个线程,直到收到另外一个线程发出的通知或者超时时,才会唤醒当前阻塞的线程。条件变量需要和互斥量配合起来使用,C11 提供了两种条件变量: condition_variable:需要配合 std::unique_lockstd::m
阅读全文
摘要:解决多线程数据混乱的方案就是进行线程同步,最常用的就是互斥锁,在 C++11 中一共提供了四种互斥锁: std::mutex:独占的互斥锁,不能递归使用 std::timed_mutex:带超时的独占互斥锁,不能递归使用 std::recursive_mutex:递归互斥锁,不带超时功能 std::
阅读全文
摘要:在某些特定情况下,**某些函数只能在多线程环境下调用一次,比如:要初始化某个对象,而这个对象只能被初始化一次,**就可以使用 std::call_once() 来保证函数在多线程环境下只能被调用一次。使用 call_once() 的时候,需要一个 once_flag 作为 call_once() 的
阅读全文
摘要:在 C++11 中不仅添加了线程类,还添加了一个关于线程的命名空间 std::this_thread,在这个命名空间中提供了四个公共的成员函数,通过这些成员函数就可以对当前线程进行相关的操作了。 get_id() 调用命名空间 std::this_thread 中的 get_id() 方法可以得到当
阅读全文
摘要:C++11 中提供的线程类叫做 std::thread,基于这个类创建一个新的线程非常的简单,只需要提供线程函数或者函数对象即可,并且可以同时指定线程函数的参数。我们首先来了解一下这个类提供的一些常用 API: 构造函数 // ① thread() noexcept; // ② thread( th
阅读全文
摘要:C++11 中提供了日期和时间相关的库 chrono,通过 chrono 库可以很方便地处理日期和时间,为程序的开发提供了便利。chrono 库主要包含三种类型的类:时间间隔duration、时钟clocks、时间点time point。 基本常识 1.时间点的来源:钟(c++的不同类) 2.时间点
阅读全文
摘要:今天我们讲一个特殊的专题,如何使用可变模板和 tuple 来完成一些常见的功能,尤其是编译期计算。 可变模板 可变模板 是 C++11 引入的一项新功能,使我们可以在模板参数里表达不定个数和类型的参数。从实际的角度,它有两个明显的用途: 用于在通用工具模板中转发参数到另外一个函数 用于在递归的模板中
阅读全文
摘要:概述 1.消息队列与命名管道有许多相似之处,但少了在打开和关闭管道方面的复杂性。但使用消息队列并未解决我们在使用命名管道时遇到的一些问题,比如管道满时的阻塞问题 2.消息队列提供了一种在两个不相关的进程之间传递数据的相当简单且有效的方法。与命名管道相比,消息队列的优势在于,它独立于发送和接受进程而存
阅读全文
摘要:接下来我们介绍一种简单而高效的进程间通信的方式! 共享内存 注意了是通信也就是数据交换,如果要想避免同时读写发生的同步问题就得需要其他机制! 在实际编程中,常用的同步机制有 信号量、传递消息(使用管道或IPC消息)、生成信号。 但是在这次的实现里面我们用自己提供的非常丑陋的同步标志written_b
阅读全文
摘要:#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/sem.h> /*程序目的: 1、完成两个进程的同步 2、每个进程进入临界区后输出一对字符 3、主进程输出‘X',其余进程输出'O' 4、主进程负责创建和
阅读全文
摘要:问题导向 我们想要把各种不同的数据类型输出的话? 就算是用printf也避免不了%d,%s等等复杂的东西。 我们的愿望? 有这样一个类似容器的东西,不管是什么基本类型只要丢进去就会自动转化为字符串那太好了。有种万众归一的感觉。 概述 定义了三个类:istringstream、ostringstrea
阅读全文
摘要:上一讲我们初步介绍了函数对象和 lambda 表达式,今天我们来讲讲它们的主要用途——函数式编程 一个小例子 如果给定一组文件名,要求数一下文件里的总文本行数,你会怎么做? 函数的原型: 我们期待接受两个 C 字符串的迭代器,用来遍历所有的文件名;返回值代表文件中的总行数。 int count_li
阅读全文
摘要:首先我们看一下在python中如何简单的实现的: 再来看C语言的实现: #include <stdio.h> #include <string.h> int main() { char a[] = "www.baidu.com"; char *p = NULL; //用来保存strtok分割后的字串
阅读全文
摘要:#include <stdio.h> #include <string.h> int countStr(char* str, char* substr) { char *p = strstr(str, substr); //问题的关键在这个函数,会返回第一个匹配到的位置 int count = 0;
阅读全文
摘要:C++98 的函数对象 函数对象(function object) 自 C++98 开始就已经被标准化了。从概念上来说,函数对象是一个可以被当作函数来用的对象。它有时也会被叫做 functor,但这个术语在范畴论里有着完全不同的含义,还是不用为妙——否则玩函数式编程的人可能会朝着你大皱眉头的。 下面
阅读全文
摘要:初识 constexpr 我们先来看一些例子: int sqr(int n) { return n * n; } int main() { int a[sqr(3)]; } 想一想,这个代码合法吗?看过之后,再想想这个代码如何? int sqr(int n) { return n * n; } in
阅读全文
摘要:模板里的一个特殊概念——替换失败非错(substitution failure is not an error),英文简称为 SFINAE。 函数模板的重载决议 我们之前已经讨论了不少模板特化。我们今天来着重看一个函数模板的情况。当一个函数名称和某个函数模板名称匹配时,重载决议过程大致如下: 根据名
阅读全文
摘要:分治算法 概念 在计算机科学中,分治法是一种很重要的算法。字面上的解释是“分而治之”,就是把一一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题.....直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。 步骤 分治法在每-层递归上都有三个步骤: 分解:将原问
阅读全文
摘要:这一讲我们来看一下模板的另外一种重要用途——编译期计算,也称作“模板元编程”。 编译期计算 首先,我们给出一个已经被证明的结论:C++ 模板是图灵完全的 这句话的意思是,使用 C++ 模板,你可以在编译期间模拟一个完整的图灵机,也就是说,可以完成任何的计算任务。 一个小例子 template <in
阅读全文
摘要:面向对象和多态 在面向对象的开发里,最基本的一个特性就是“多态” ——用相同的代码得到不同结果。以我们在[第 1 讲] 提到过的 shape 类为例,它可能会定义一些通用的功能,然后在子类里进行实现或覆盖: class shape { public: … virtual void draw(cons
阅读全文
摘要:F.20 《C++ 核心指南》的 F.20 这一条款是这么说的 : F.20: For “out” output values, prefer return values to output parameters 翻译一下: 在函数输出数值时,尽量使用返回值而非输出参数 这条可能会让一些 C++ 老
阅读全文
摘要:自定义字面量 字面量(literal)是指在源代码中写出的固定常量,它们在 C++98 里只能是原生类型,如: "hello",字符串字面量,类型是 const char[6] 1,整数字面量,类型是 int 0.0,浮点数字面量,类型是 double 3.14f,浮点数字面量,类型是 float
阅读全文
摘要:#include <stdio.h> #include <WinSock2.h> #include <windows.h> //gbk -> utf-16 int test1() { char text_gbk[256] = "砂隐村"; //字符串字面常量,取决于cpp文件自身的 wchar_t
阅读全文
摘要:如果要挑选 C++11 带来的最重大改变的话,自动类型推断肯定排名前三。如果只看易用性或表达能力的改进的话,那它就是“舍我其谁”的第一了。 auto 自动类型推断,顾名思义,就是编译器能够根据表达式 (注意是“表达式”!!接下来会和decltype对比) 的类型,自动决定变量的类型(从 C14 开始
阅读全文
摘要:什么是迭代器? 迭代器是一个很通用的概念,并不是一个特定的类型。它实际上是一组对类型的要求([1])。它的最基本要求就是从一个端点出发,下一步、下一步地到达另一个端点。按照一般的中文习惯,也许“遍历”是比“迭代”更好的用词。我们可以遍历一个字符串的字符,遍历一个文件的内容,遍历目录里的所有文件,等等
阅读全文
摘要:最短路径 Floyed算法 解决的问题 求解任意两点之间的最短路径 可以处理带有负权边的图, 但不能处理带有“负环”的图 思想 对于要求解的两个点,我们给定任意一个点作为中间点,经过中间点的路径有没有可能比直接到达更短? 动态规划的思想 时间复杂度 一个小例子 #include <cstdio> #
阅读全文
摘要:并查集 并查集是一种树形数据结构,用于处理一些不相交集合的合并及查询问题。 常见的用途有求连通子图、求最小生成树的Kruskal算法和求最近公共祖先(LCA)等。 创建并查集只需要三个步骤。 算法步骤 初始化。把每个点所在集合初始化为其自身。 查找。查找两个元素所在的集合,即找祖宗。 合并。如果两个
阅读全文
摘要:函数对象及其特化 在讲容器之前,我们需要首先来讨论一下两个重要的函数对象,less 和 hash。 我们先看一下 less,小于关系。在标准库里,通用的 less 大致是这样定义的: template <class T> struct less : binary_function<T, T, boo
阅读全文
摘要:string string 一般并不被认为是一个 C++ 的容器。但鉴于其和容器有很多共同点,我们先拿 string 类来开说。 string 是模板 basic_string 对于 char 类型的特化,可以认为是一个只存放字符 char 类型数据的容器。“真正”的容器类与 string 的最大不
阅读全文
摘要:移动语义是 C11 里引入的一个重要概念;理解这个概念,是理解很多现代 C 里的优化的基础。 值分左右 我们常常会说,C++ 里有左值和右值。这话不完全对。标准里的定义实际更复杂,规定了下面这些值类别(value categories): 我们先理解一下这些名词的字面含义: 一个 lvalue 是通
阅读全文
摘要:第一步:针对单独类型的模板 为了完成智能指针首先第一步的想法。 class shape_wrapper { public: explicit shape_wrapper( shape* ptr = nullptr) : ptr_(ptr) {} ~shape_wrapper() { delete p
阅读全文
摘要:基本概念 堆,英文是 heap,在内存管理的语境下,指的是动态分配内存的区域。这个堆跟数据结构里的堆不是一回事。这里的内存,被分配之后需要手工释放,否则,就会造成内存泄漏。 C++ 标准里一个相关概念是自由存储区,英文是 free store,特指使用 new 和 delete 来分配和释放内存的区
阅读全文