20145236《信息安全系统设计基础》第13周学习总结

20145236《信息安全系统设计基础》第13周学习总结

第11章 网络编程

网络应用随处可见。任什么时候候你浏览Web、发送邮件,你就在使用一个网络应用程序。有趣的是,全部网络应用都是基于相同的基本编程模型,有着类似的总体逻辑结构,而且依赖相同的编程接口。git

11.1客户端-服务器编程模型

  1. 每一个网络应用都是基于客户端-服务器模型的。采用这个模型,一个应用是由一个服务器户端提供某种服务。服务器管理某种资源,而且经过操做这种资源来为它的客户端提供某种服务。—个FTP服务器就管理了一组磁盘文件,它为客户端进行它会为客户端进行存储和检索。类似地一个电子邮件服务器管理了一些文件,它为客户端进行读和更新。
  2. 一个客户端-服务器事务由四步组成:
    (1) 当一个客户端须要服务时,它向服务器发送一个请求,发起一个事务。
    (2) 服务器收到请求后,解释它,并以适当的方式操做它的资源。
    (3) 服务器给客户端发送一响应,并等待下一个请求。
    (4) 客户端收到响应并处理它。例如,当Web浏览器收到来自服务器的一页后,它就在屏幕上显示此页。

11.2 网络

客户端和服务器一般运行在不一样的主机上,而且经过计算机网络的硬件和软件资源来通讯。
对于一个主机而言,网络只是又一种I/O设备,做为数据源和数据接收方。一个插到I/O总线扩展槽的适配器提供了到网络的物理接口。从网络上接收到的数据从适配器通过I/O和存储器总线拷贝到存储器,典型地是经过DMA传送。
web

  1. 一个以太网段,包括电缆(一般是双绞线)和一个叫作集线器的小盒子。每根电缆都有相同的最大位带宽。集线器不加分辩地将一个端口上收到的每一个位复制到其余全部的端口上。所以,每台主机都能看到每一个位。
  2. 每一个以太网适配器都有—个全球惟一的48位地址,它存储在这个适配器的非易失性存储器上。一台主机能够发送一段位,称为帧。每一个主机适配器都能看到这个帧,可是只有目的主机实际读取它。
  3. 桥接以太网是使用一些电缆和叫作网桥的小盒子,将多个以太网段链接起来造成的较大的局域网。电缆的带宽能够是不一样的。
  4. 网桥比集线器更充分地利用了电缆带宽。
  5. 在层次的更高级别中,多个不兼容的局域网能够经过叫作路由器的计算机链接起来,组成一个Internet。
  6. 解决办法是一层运行在每台主机和路由器上的协议软件,它消除了不一样网络之间的差别。
  7. 协议必须提供两种基本能力:
    • 命名机制。不一样的局域网技术有不一样的和不兼容的方式来为主机分配地址。
    • 传送机制。在电缆上编码位和将这些位封装成帧方面,不一样的联网技术有不一样和不兼容的方式。一个包是由包头和有效载荷组成,其中包头包括包的大小以及源主机和目的主机的地址,有效载荷包括从源主机发出的数据位。
  8. 互联网思想的精髓,封装是关键。

11.3 全球IP因特网

  • 全球IP因特网是最著名和最成功的互联网络实现。每台因特网主机都运行实现TCP/TP协议的软件,几乎每一个现代计算机系统都支持这个协议。因特网的客户端和服务器混合使用套接字接口函数和Unix I/O函数来进行通讯。套接字函数典型地是做为会陷入内核的系统调用来实现的,并调用各类内核模式的TCP/IP函数。
  • 把因特网看作一个世界范围的主机集合,知足如下特性:
    • 主机集合被映射为一组32位的IP地址。
    • 这组IP地址被映射为一组称为因特网域名的标识符。
    • 因特网主机上的进程可以经过链接和任何其余因特网主机上的进程通讯。

11.4套接字接口

listen函数将sockfd从一个主动套接字转化为一个监听套接字。该套接字能够接受来自客户端的链接请求。backlog参数暗示了内核在开始拒绝链接请求以前,该放入队列中等待的未完成链接请求的数量。数据库

11.5Web服务器

Web客户端和服务器之间的交互用的是一个基于文本的应用级协议,叫作HTTP。HTTP是一个简单的协议。一个web客户端(即浏览器)打开一个到服务器的因特网链接。浏览器读取这些内容,并请求某些内容。服务器响应所请求的内容,而后关闭链接。浏览器读取并把它显示在屏幕内主要的区别是Web内容能够用HTML来编写。一个HTML程序(页)包含指令(标记)它们告诉浏览器如何显示这页中的各类文本和图形对象。编程

第12章 并发编程

到目前为止,咱们主要将并发看作是一种操做系统内核用来运行多个应用程序的机制。可是,并发不只仅局限于内核。它也能够在应用程序中扮演重要角色。例如,咱们已经看到Unix信号处理程序如何容许应用响应异步事件,例如用户键入。或者程序访问虚拟存储器的个未定义的区域.应用级并发在其余状况下也是颇有用的。浏览器

12.1基于进程的并发编程

在接受链接请求以后,服务器派生一个子进程,这个子进程得到服务器描述符表的完整拷贝。子进程关闭它的拷贝中的监听描述符3,而父进程关闭它的已链接描述符4的拷贝,由于再也不须要这些描述符了。这就获得了图中的状态,其中子进程正忙于为客户端提供服务。由于父子进程中的已链接描述符都指向同一个文件表表项,因此父进程关闭它的已链接描述符的拷贝是相当重要的。不然,将永远不会释放已链接描述符4的文件表条目,并且由此引发的存储器泄漏将最终消耗尽可用的存储器,使系统崩溃。如今假设在父进程为客户端1建立了子进程以后,它接受一个新的客户端2的链接请求,并返回一个新的已链接描述符(好比描述符5)如图所示。而后,父进程又派生另外一个子进程,这个子进程用已链接描述符5为它的客户端提供服务,如图所示。此时,父进程正在等待下一个链接请求,而两个子进程正在形地为它们各自的客户端提供服务。
安全

12.2基于I/O多路复用的并发编程

一个服务器,它有两个I/O事件:1)网络客户端发起链接请求,2)用户在键盘上键入命令行。咱们先等待那个事件呢?没有那个选择是理想的。若是accept中等待链接,那么没法相应输入命令。若是在read中等待一个输入命令,咱们就不能响应任何链接请求(这个前提是一个进程)。
针对这种困境的一个解决办法就是I/O多路复用技术。基本思想是:使用select函数,要求内核挂起进程,只有在一个或者多个I/O事件发生后,才将控制返给应用程序。如图所示:横向的方格能够看做是一个n位的描述符向量。如今,咱们定义第0位描述是“标准输入”,第3位描述符是“监听描述符”。服务器

12.3基于线程的并发编程

每一个线程都有本身的线程上下文,包括一个线程ID、栈、栈指针、程序计数器、通用目的寄存器和条件码。全部的运行在一个进程里的线程共享该进程的整个虚拟地址空间。因为线程运行在单一进程中,所以共享这个进程虚拟地址空间的整个内容,包括它的代码、数据、堆、共享库和打开的文件。
1、线程执行模型网络

  1. 主线程
  2. 对等线程
  3. 主线程切换到对等线程

2、Posix线程多线程

Posix线程是C程序中处理线程的一个标准接口。并发

万能函数:

void func(void parameter)
typedef void (uf)(void para)

3、建立线程

1.建立线程:
pthread_create函数

#include <pthread.h>
typedef void (func)(void );

int pthread_create(pthread_t tid, pthread_attr_t attr, func f, void arg);
功能:建立一个新的线程,带着一个输入变量arg,在新线程的上下文运行线程例程f。

2.查看线程ID
pthread_self函数

#include <pthread.h>

pthread_t pthread_self(void);
功能:返回调用者的线程ID(TID)

4、终止线程

1.终止线程的方式:隐式终止、显示终止

2.pthread_exit函数

#include <pthread.h>

void pthread_exit(void *thread_return);

3.pthread_cancle函数

#include <pthread.h>

void pthread_cancle(pthread_t tid);

5、回收已终止线程的资源

pthread_join函数:

#include <pthread.h>

int pthread_join(pthread_t tid,void **thrad_return);

6、分离线程
pthread_detach函数

#include <pthread.h>

void pthread_detach(pthread_t tid);
功能:分离可结合线程tid。

7、初始化线程
pthread_once函数

#include <pthread.h>
pthread_once_t once_control = PTHREAD_ONCE_INIT;

int pthread_once(pthread_once_t once_control, void (init_routine)(void));

12.4多线程程序中的共享变量

全局变量和static变量是存储在数据段,因此多线程共享之!因为线程的栈是独立的,全部线程中的自动变量是独立的。即便多个线程运行同一段代码总的自动变量,那么他们的值也是根据线程的不一样而不一样。

12.5用信号量同步线程

信号量一般称之为PV操做,虽然它的思想是将临界代码保护起来,达到互斥效果。这里面操做系统使用到了线程挂起。
将线程i的循环代码分解成五个部分:

12.6使用线程提升并行性

到目前为止,在对并发的研究中,咱们都假设并发线程是在单处许多现代机器具备多核处理器。并发程序一般在这样的机器上运理器系统上执行的。然而,在多个核上并行地调度这些并发线程,而不是在单个核顺序地调度,在像繁忙的Web服务器、数据库服务器和大型科学计算代码这样的应用中利用这种并行性是相当重要的。

代码实践部分

condvar.c
运行结果:

mutex用于保护资源,wait函数用于等待信号,signal函数用于通知信号,wait函数中有一次对`mutex的释放和从新获取操做,所以生产者和消费者并不会出现死锁。

share.c
运行结果:

得到线程的终止状态,thr_fn 1thr_fn 2thr_fn 3三个函数对应终止线程的三种方法,即从线程函数return,调用pthread_exit终止本身和调用pthread_cancel终止同一进程中的另外一个线程。

countwithmutex.c
运行结果:

引入互斥锁(Mutex),得到锁的线程能够完成”读-修改-写”的操做,而后释放锁给其它线程,没有得到锁的线程只能等待而不能访问共享数据。

semphore.c
运行结果:

semaphore表示信号量,semaphore变量的类型为sem_t,sem_init()初始化一个semaphore变量,value参数表示可用资源 的数量,pshared参数为0表示信号量用于同一进程的线程间同步。

count.c
运行结果:

这是一个不加锁的建立两个线程共享同一变量都实现加一操做的程序,在这个程序中虽然每一个线程都给count加了5000,但因为结果的互相覆盖,最终输出值不是10000,而是5000。

代码托管

代码连接

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 200/200 2/2 20/20
第二周 200/400 2/4 18/38
第三周 100/500 1/5 10/48
第四周 250/750 1/6 10/58
第五周 100/850 1/7 10/68
第六周 100/950 1/8 12/80
第七周 200/1150 1/9 12/92
第八周 124/1274 2/11 10/102
第九周 205/1479 2/13 5/107
第十周 333/1712 2/15 10/117
第十一周 758/2470 3/18 12/129
第十二周 25/2495 3/21 10/139
第十三周 956/3451 1/22 10/149
相关文章
相关标签/搜索