- 博客(222)
- 资源 (4)
- 收藏
- 关注
原创 第6章 线程通信
信号量实际上就是一个简单的整数,一个进程在信号变成0或者1的情况下推进,并且将信号变为1或0来防止其他进程推进.当进程任务完成后,则将信号再改变为0或1,从而允许其他进程执行。如果要在两个不相关的线程,如两个不同进程里面的线程,之间进行管道通信,则需要使用记名管道.记名管道与文件系统共享一个名字空间.信号就是一个内核对象,或者一个内核数据结构.发送方将该数据结构的内容填写好,并指明该信号的目标进程后,发出特定的软件中断.共享内存就是两个进程共同拥有同一片内存,这片内存中的任何内容,二者均可以访问.
2023-01-08 14:37:20
348
原创 13.6-14.8读书笔记
不同类型可能具有相同的调用形式// 普通函数 int add(int i , int j) {} // lambda,产生一个未命名函数对象类 auto mod = [ ](int i , int j) {} // 函数对象类 struct divide {};// 构建从运算符到函数指针的映射关系,其中函数接受两个int,返回一个int map < string , int(*)(int , int) > binops;但是我们不能将mod或者divide存入binops,因为mod是个。
2023-01-02 22:16:40
462
原创 11.1 -11.3章读书笔记
解释map和set的区别。你如何选择使用哪个?map 是键值对,而 set 只有键没有值。当我需要存储键值对的时候使用 map,而只需要键的时候使用 set。解释set和list 的区别。你如何选择使用哪个?set 是有序不重复集合,底层实现是红黑树,而 list 是无序可重复集合,底层实现是链表。定义一个map,关键字是家庭的姓,值是一个vector,保存家中孩子(们)的名。编写代码,实现添加新的家庭以及向已有家庭中添加新的孩子。= "@q";)= "@q";)
2022-11-27 21:28:08
278
原创 9.4-9.6 章读书笔记
string s(s2, pos2, len2) s是从string s2从下标pos2开始len2字符的拷贝。string s(s2, pos2) s是string s2从下标pos2开始的字符的拷贝。string s(cp, n) s是指向数组中前n个字符的拷贝。
2022-11-27 21:13:42
241
原创 10.1- 10.3读书笔记
头文件 algorithm 中定义了一个名为 count 的函数,它类似 find, 接受一对迭代器和一个值作为参数。count 返回给定值在序列中出现的次数。编写程序,读取 int 序列存入vector中,打印有多少个元素的值等于给定值。
2022-11-13 23:23:53
208
原创 9.1-9.3读书笔记
对于下面的程序任务,vector、deque和list哪种容器最为适合?解释你的选择的理由。如果没有哪一种容器优于其他容器,也请解释理由。(a) 读取固定数量的单词,将它们按字典序插入到容器中。我们将在下一章中看到,关联容器更适合这个问题。(b) 读取未知数量的单词,总是将单词插入到末尾。删除操作在头部进行。© 从一个文件读取未知数量的整数。将这些数排序,然后将它们打印到标准输出。(a) list ,因为需要频繁的插入操作。(b) deque ,总是在头尾进行插入、删除操作。
2022-10-23 16:39:55
114
原创 7.6-8.3读书笔记
编写函数,接受一个istream&参数,返回值类型也是istream&。完成这些操作后,在返回流之前,对流进行复位,使其处于有效状态。编写函数,以读模式打开一个文件,将其内容读入到一个string的vector中,将每一行作为一个独立的元素存于vector中。与类本身相关,而不是与类的各个对象相关的成员是静态成员。静态成员能用于某些场景,而普通成员不能。如果 badbit、failbit、eofbit 的任一个被置位,那么检测流状态的条件会失败。什么是类的静态成员?静态成员与普通成员有何区别?
2022-10-16 21:44:27
276
原创 7.3-7.5读书笔记
解释下面代码的含义,说明其中的Type和initVal分别使用了哪个定义。如果我们把第256页Screen类的pos的typedef放在类的最后一行会发生什么情况?类型名的定义通常出现在类的开始处,这样就能确保所有使用该类型的成员都出现在类名的定义之后。如果成员使用了外层作用域中的某个名字,而该名字代表一种类型,则类不能在之后重新定义该名字。定义一对类X 和Y,其中X 包含一个指向 Y 的指针,而Y 包含一个类型为 X 的对象。下面的初始值是错误的,请找出问题所在并尝试修改它。
2022-10-10 09:52:14
417
原创 6.7-7.2 读书笔记
为什么read函数将其Sales_data参数定义成普通的引用,而print函数将其参数定义成常量引用?因为read函数会改变对象的内容,而print函数不会。在下面这条if语句中,条件部分的作用是什么?read 函数的返回值是 istream 对象,if语句中条件部分的作用是从输入流中读取数据给两个data对象。编写一个构造函数,令其用我们提供的类内初始值显式地初始化成员。
2022-09-25 22:36:40
348
原创 5.5-6.2读书笔记
实参是函数调用的实际值,是形参的初始值。应该改为下面这样:6.1 参数传递void f(T) 的参数通过值传递,在函数中 T 是实参的副本,改变T不会影响到原来的实参。void f(&T) 的参数通过引用传递,在函数中的T是实参的引用,T的改变也就是实参的改变。、因为字符串可能很长,因此使用引用避免拷贝;而在函数中我们不希望改变 s 的内容,所以令 s 为常量。occurs 是要传到函数外部的变量,所以使用引用,occurs 的值会改变,所以是普通引用。因为我们只需要 c 的值,
2022-09-12 22:53:57
267
原创 4.1-4.12读书笔记
如果 someValue的值为真,x 和 y 的值都自增并返回 y 值,然后丢弃 y 值,y递减并返回 y 值。如果一台机器上 int 占 32 位、char 占8位,用的是 Latin-1 字符集,其中字符’q’ 的二进制形式是 01110001,那么表达式’q’ ...
2022-08-28 22:51:38
321
原创 1.5 内存不够怎么办
把地址空间人为地等分成固定大小的页,每一页由硬件决定,或者硬件支持多种大小的页。思路是把一段与程序所需要的内存空间大小的虚拟空间映射到某个地址空间。
2022-08-28 14:50:52
838
原创 3.1-3.3 读书笔记
要根据for循环中的代码来看是否合法,c是string 对象中字符的引用,s是常量。因此如果for循环中的代码重新给c赋值就会非法,如果不改变c的值,那么合法。(1)string:类似 is >> s 的读取,string对象会忽略开头的空白并从第一个真正的字符开始,直到遇见下一空白为止。下列vector对象的定义有不正确的吗?对于不正确的,说明其错误的原因。如果想定义一个含有10个元素的vector对象,所有元素的值都是42,请例举三种不同的实现方法,哪种方式更好呢?如果合法,c的类型是什么?...
2022-08-07 22:36:53
142
原创 第2章 变量和基本类型读书笔记
解释下列定义的含义,对于非法的定义,请说明错在何处并将其改正。(a)std(a)应该先定义再使用。std(b)用列表初始化内置类型的变量时,如果存在丢失信息的风险,则编译器将报错。©在这里wage是未定义的,应该在此之前将其定义。(d)不报错,但是小数部分会被截断。下列变量的初值分别是什么?stdintmain(){std}这里是引用global_int是全局变量,所以初值为0。......
2022-08-01 09:03:18
224
原创 4.2 Virtual Member Functions
一般实现模型每个class有一个virtualtable,内含该class之中有作用的的地址,然后每个object有一个vptr,指向所在;下图为Point的内存布局和其。
2022-07-23 14:44:21
158
原创 4.1 Member的各种调用方式
不应该带来什么额外负担,因为编译器内部已经将“member函数实例”转换为对等的“nonmember函数实例”,通过"namemanglin",都可以绝对清楚指出来。为什么编译器要这么做?
2022-07-17 15:59:15
189
原创 3.2:Data Member的布局 && 3.3:Data member的存取
考虑如下代码:在中排列顺序將和被声明的顺序一样,任何中间介入的都不会放进对象布局之中;存放在中考虑如下代码:每一个只有一个实体,存在在程序的之中,每次程序调用,就会被内部转化为对该唯一的实体直接操作,例如:从指令执行观点来看,这是C++语言中"通过一个指针和通过一个对象来获取member",结论完全相同的唯一一种情况;直接存放在每一个之中,只要程序员在一个中直接处理一个,所谓就会发生表面上看到对于的直接存取,事实上是经由一个(this指针)完成的...
2022-06-05 14:38:54
150
原创 3.1 Data Member的绑定
考虑如下代码:extern float x = 6.66;class Point3d {public: float X() {return x;}private: float x, y, z;};Point3d::X() 传回来的是Point3d内部的x; 而在早期的的C++编译器上,该操作会指向global x object!并因此导出早期C++的两种防御性程序设计风格:把所有的 data members放在class的声明起头处,以保证正确的绑定class Po
2022-05-22 14:42:05
221
原创 Data语意学
考虑如下代码:class X{};class Y : public virtual X{};class Z : public virtual X{};class A : public Y, public Z{};cout << sizeof(X) << sizeof(Z) << sizeof(Y) << sizeof(A) ;结果为:1 8 8 16;class X{};并不是空的,它有一个隐藏的1byte大小,那是被编译器安插进去的一个ch
2022-05-21 11:17:17
128
原创 2.4成员们的初始化队伍
在下列情况下,为了让你的程序能够被顺利编译,你必须使用member initialization list当初始化一个reference member时;当初始化一个const member时;当调用一个base class的constructor,而它拥有一组参数时当调用一个member class的constructor,而它拥有一组参数时;考虑如下代码:class Word { string _name; int _cnt;public: Word() { _name
2022-05-02 15:54:48
312
原创 2.3程序转化语意学
显示的初始化操作已知有如下代码:X x0void foo_bar() { X x1(x0); // 定义另了x1,x2,x3 X x2 = x0; X x3 = X(x0);}上述必要的程序转化有两个阶段:重写每一个定义,其中的初始化操作会被剔除class的copy constructor调用操作会被安插进去在明确双阶段转化后,foo_bar()可能看起来像这样:// 伪代码void foo_bar() { X x1; 定义重写,其中的初始化操作会被剔除 X x2;
2022-04-30 15:42:27
264
原创 第 33 章 基于事件的并发(进阶)
33.1 基本想法:事件循环在深入细节之前,我们先看一个典型的基于事件的服务器。这种应用都是基于一个简单的结构,称为事件循环(event loop)。while (1) { events = getEvents(); for (e in events) processEvent(e);}主循环等待某些事件发生(通过 getEvents()调用),然后依次处理这些发生的事件。处理事件的代码叫作事件处理程序(event handler)。重要的是,处理程序在处理一个事件时,它是系统中发生的唯一活
2022-04-09 13:58:17
349
原创 2.2 Copy Constructor 的构造操作
拷贝构造函数会在如下三种情况下调用:以object的内容初始化另一个class object的初值当object被当作参数交给某个函数时当函数传回一个class object时Default Memberwise Initialization如果 class没有提供一个explicit copy constructor又当如何?当class object以相同class的另一个object作为初始值,其内部是以所谓default memberwise initialization手法完成的:
2022-03-30 23:11:05
199
原创 第32章 常见并发问题
32.1 有哪些类型的缺陷非死锁的缺陷死锁缺陷32.2 非死锁缺陷违反原子性缺陷: Thread 1:: if (thd->proc_info) { ... fputs(thd->proc_info, ...); ... } Thread 2:: thd->proc_info = NULL;这个例子中,两个线程都要访问 thd 结构中的成员 proc_info。第一个线程检查 proc_info非空,然后打印出值;第二个线程设置其为空。显然,当第一个线程检查
2022-03-28 22:54:05
459
原创 第31章 信号量
31.1 信号量的定义信号量是有一个整数值的对象,可以用两个函数来操作它。在 POSIX 标准中,是sem_wait()和 sem_post()1。#include <semaphore.h>sem_t s;sem_init(&s, 0, 1);其中申明了一个信号量 s,通过第三个参数,将它的值初始化为 1。sem_init()的第二个参数,在我们看到的所有例子中都设置为 0,表示信号量是在同一进程的多个线程共享的。31.2 二值信号量(锁)信号量的第一种用法是我们已经熟
2022-03-26 14:34:28
1547
原创 第30章 条件变量
,在很多情况下,线程需要检查某一条件(condition)满足之后,才会继续运行。例如,父线程需要检查子线程是否执行完毕 [这常被称为 join()]。这种等待如何实现呢?我们可以尝试用一个共享变量,如图 30.2 所示。这种解决方案一般能工作,但是效率低下,因为主线程会自旋检查,浪费 CPU 时间。我们希望有某种方式让父线程休眠,直到等待的条件满足(即子线程完成执行)。 volatile int done = 0; void *child(void *arg) { printf("child\
2022-03-20 14:19:56
1049
原创 2.1 Default Contstructor 构造函数
考虑如下代码:class Foo {public: int val; Foo *extent;}void foo_bar(){ Foo bar; // 要求bar's members都被清0 if(bar.val || bar.pnext){ // ... }}上述代码语义是要求Foo有一个default contructor可以將它的两个members初始化为0。可是编译器却不会为你做这件事情。带有deafault constrcutor的member class ob
2022-03-20 11:49:25
691
原创 第29章基于锁的并发数据结构
29.1 并发计数器如下为一个非并发的计数器: typedef struct counter_t { int value; } counter_t; void init(counter_t *c) { c->value = 0; } void increment(counter_t *c) { c->value++; } void decrement(counter_t *c) { c->value--; } int get(counter_t *
2022-03-16 22:40:19
557
原创 第28章 锁
程序员在源代码中加锁,放在临界区周围,保证临界区能够像单条原子指令一样执行。28.1锁的基本思想 lock_t mutex; // some globally-allocated lock 'mutex' lock(&mutex); balance = balance + 1; unlock(&mutex);锁就是一个变量,因此我们需要声明一个某种类型的锁变量(lock variable,如上面的mutex),才能使用。这个锁变量(简称锁)保存了锁在某一时刻的状态。它要么是可用
2022-03-09 22:17:33
550
原创 第27章 插叙: 线程API
27.1 线程创建#include <assert.h>#include <stdio.h>#include <pthread.h>typedef struct { int a; int b;} myarg_t;void *mythread(void *arg) { myarg_t *args = (myarg_t *) arg; printf("%d %d\n", args->a, args->b);
2022-03-07 22:33:34
224
原创 第26章 并发:介绍
本章将介绍为单个运行进程提供的新抽象:线程(thread)。经典观点是一个程序只有一个执行点(一个程序计数器,用来存放要执行的指令),但多线程(multi-threaded)程序会有多个执行点(多个程序计数器,每个都用于取指令和执行) 。换一个角度来看,每个线程类似于独立的进程,只有一点区别:它们共享地址空间,从而能够访问相同的数据。26.1 实例:线程创建#include <stdio.h>#include <stdlib.h>#include <pthread.h
2022-03-03 23:06:17
279
原创 第19章 分页:快速地址转换(TLB)
使用分页作为核心机制来实现虚拟内存,可能会带来较高的性能开销。因为要使用分页,就要将内存地址空间切分成大量固定大小的单元(页),并且需要记录这些单元的地址映射信息
2022-03-02 22:21:47
593
原创 1.3 对象的差异
C++程序设计支持三种programming paradigms(程序设计范式)程序模型抽象数据模型面向对象模型你C++以下列方法支持多态经由一组隐式的转化操作。例如把一个drived class指针转化为一个指向public base type的指针shape *ps = new circle();经virtual function机制ps->rotate();经由dynamic_cast和typeid运算符if (cicle *pc = dynamic_ca
2022-03-01 22:59:04
545
原创 1.2 关键词所带来的差异
关键词的困扰如果struct关键词的使用实现了C的数据抽象观念,而class关键词实现的是C++的ADT观念,那么当然“不一致性”是一种错误的语言用法;就像一个object被矛盾的声明为static和extern:static int foo;extern int foo;策略性正确的structC struct在C++中的一个合理用途,是当你要传递“一个复杂的class object的全部或部分”到某个C函数去时,struct声明可以將数据封装起来,并保证有与C兼容的空间布局。然而这项保证只有
2022-02-27 15:34:46
469
原创 条款49:了解new-handler的行为
考虑如下代码:void outOfMem() { std::cerr << "unable to satisfy request for memory\n"; std::abort();}int main() { std::set_new_handler(outOfMem); int *p = new int[1000000000000000]; //异常 return 0;}当operator new无法满足内存申请时,它会不断调用new-
2022-02-09 19:06:02
568
原创 条款47:请使用traits classes表现类型信息
假定我们有一个名为advance,用来將某个迭代器移动某个距离:template<typename IterT, typename DistT> // 將迭代器移动d个单位void advance(IterT &iter, DistT d);STL迭代器分类有5种:intput迭代器,只能向前移动,一次一步,只可以读取,如istream_iterators,只能读取一次output迭代器,只能向前移动,一次一步,只可以涂写,如otream_iterators,只能涂写一次
2022-02-08 18:11:10
804
原创 条款34:优先选用lambda式,而非std::bind
称std::bind返回的函数对象为绑定对象。考虑在程序的某处我们想要设置在一小时后发出警报并持续30秒,考虑如下代码:using Time = std::chrono::steady_clock::time_point;enum class Sound {Beep, Siren, Whistle};using Duration = std::chrono::steady_clock::duration;// 在时刻t,发出声音s,持续时常dvoid setAlarm(Time t, Soun
2022-01-08 16:33:40
367
《Flash.ActionScript3.0从入门到精通》笔记 (1)
2018-06-11
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人