unix-2

1、fopen和open区别

 1 前者属于低级IO,后者是高级IO。
 2 前者返回一个文件描述符,后者返回一个文件指针。
 3 前者无缓冲,后者有缓冲。
 4 前者与 read, write 等配合使用, 后者与 fread, fwrite等配合使用。
 5 后者是在前者的基础上扩充而来的,在大多数情况下,用后者。 
 6 
 7 1.open 是系统调用 返回的是文件句柄,文件的句柄是文件在文件描述副表里的索引,fopen是C的库函数,返回的是一个指向文件结构的指针。
 8 2.fopen是ANSIC标准中的C语言库函数,在不同的系统中应该调用不同的内核api 
 9 3.fopen是标准c函数。返回文件流而不是linux下文件句柄。设备文件不可以当成流式文件来用,只能用open
10 4.fopen是用来操纵正规文件的,并且设有缓冲的,跟open还是有一些区别
11 5.一般用fopen打开普通文件,用open打开设备文件
12 6.fopen是标准c里的,而open是linux的系统调用.
13 7.他们的层次不同.
14 8.fopen可移植,open不能
15 9.我认为fopen和open最主要的区别是fopen在用户态下就有了缓存,在进行read和write的时候减少了用户态和内核态的切换,而open则每次都需要进行内核态和用户态的切换;表现为,如果顺序访问文件,fopen系列的函数要比直接调用open系列快;如果随机访问文件open要比fopen快。
View Code

 2、进程(程序 数据  进程控制块pcb)

pcb:

 1 进程控制块包含三类信息 
 2 
 3 1.标识信息。用于唯一地标识一个进程,常常分由用户使用的外部标识符和被系统使用的内部标识号。几乎所有操作系统中进程都被赋予一个唯一的、内部使用的数值型的进程号,操作系统的其他控制表可以通过进程号来交叉引用进程控制表。常用的标识信息包括进程标识符、父进程的标识符、用户进程名、用户组名等。 
 4 
 5 2.现场信息。用于保留一个进程在运行时存放在处理器现场中的各种信息,任何一个进程在让出处理器时必须把此时的处理器现场信息保存到进程控制块中,而当该进程重新恢复运行时也应恢复处理器现场。常用的现场信息包括通用寄存器的内容、控制寄存器(如PSW寄存器)的内容、用户堆战指针、系统堆饺指针等。 
 6 
 7 3.控制信息。用于管理和调度一个进程。常用的控制信息包括:l)进程的调度相关信息,如进程状态、等待事件和等待原因、进程优先级、队列指引元等2)进程组成信息,如正文段指针、数据段指针:引进程间通信相关信息,如消息队列指针、信号量等互斥和同步机制4)进程在辅存储器内的地址5)CPU资源的占用和使用信息,如时间片余量、进程己占用CPU的时间、进程己执行的时间总和,记账信息6)进程特权信息,如在内存访问和处理器状态方面的特权7)资源清单,包括进程所需全部资源、已经分得的资源,如主存资源、I/0设备、打开文件表等。 
 8 
 9 ●队列:把处于同一状态(例如就绪态)的所有进程控制块链接在一起,这样的数据结构称为进程队列(Process Queues)。 
10 
11 ●进程的创建来源于以下四个事件: 
12 
13 1.提交一个批处理作业。 
14 
15 2.在终端上交互式的登录。 
16 
17 3.操作系统创建一个服务进程。 
18 
19 4.存在的进程孵化(spawn)新的进程。 
20 
21 ●进程的创建过程如下描述: 
22 
23 1.在主进程表中增加一项,并从PCB池中取一个空白PCB。 
24 
25 2.为新进程的进程映像中的所有成分分配地址空间。对于进程孵化操作还需要传递环境变量,构造共享地址空间。 
26 
27 3.为新进程分配资源,除内存空间外,还有其它各种资源。 
28 
29 4.查找辅助存储器,找到进程正文段并装入到正文区。 
30 
31 5.初始化进程控制块,为新进程分配一个唯一的进程标识符,初始化PSW。 
32 
33 6.把进程加入某一就绪进程队列,或直接将进程投入运行。 
34 
35 7.通知操作系统的某些模块,如记账程序、性能监控程序。 
36 
37 ●进程切换的步骤 
38 
39 1.保存被中断进程的处理器现场信息。 
40 
41 2.修改被中断进程的进程控制块的有关信息,如进程状态等。 
42 
43 3.把被中断进程的进程控制块加入有关队列。 
44 
45 4.选择下一个占有处理器运行的进程。 
46 
47 5.修改被选中进程的进程控制块的有关信息。 
48 
49 6.根据被选中进程设置操作系统用到的地址转换和存储保护信息。 
50 
51 7.根据被选中进程的信息来恢复处理器现场
View Code

  进程间通信方式:

1 # 管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
2 # 有名管道 (named pipe) : 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
3 # 信号量( semophore ) : 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
4 # 消息队列( message queue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
5 # 信号 ( sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
6 # 共享内存( shared memory ) :共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。
7 # 套接字( socket ) : 套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。
View Code

  进程线程的关系

1 进程和线程的关系:
21)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。
32)资源分配给进程,同一进程的所有线程共享该进程的所有资源。
43)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。
54)处理机分给线程,即真正在处理机上运行的是线程。
65)线程是指进程内的一个执行单元,也是进程内的可调度实体。
View Code
1 线程与进程的区别:
21)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位。
32)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可以并发执行。
43)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源。
54)系统开销:在创建或撤销进程的时候,由于系统都要为之分配和回收资源,导致系统的明显大于创建或撤销线程时的开销。但进程有独立的地址空间,进程崩溃后,在保护模式下不会对其他的进程产生影响,而线程只是一个进程中的不同的执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但是在进程切换时,耗费的资源较大,效率要差些。
View Code

一个线程挂了  整个进程就挂了

3、死锁  银行家算法

4、socket模型

select 模型

  1 socket编程的select模型
  2 
  3       在掌握了socket相关的一些函数后,套接字编程还是比较简单的,日常工作中碰到很多的问题就是客户端/服务器模型中,如何让服务端在同一时间高效的处理多个客户端的连接,我们的处理办法可能会是在服务端不停的监听客户端的请求,有新的请求到达时,开辟一个新的线程去和该客户端进行后续处理,但是这样针对每一个客户端都需要去开辟一个新的线程,效率必定底下。
  4 
  5      其实,socket编程提供了很多的模型来处理这种情形,我们只要按照模型去实现我们的代码就可以解决这个问题。主要有select模型和重叠I/o模型,以及完成端口模型。这次,我们主要介绍下select模型,该模型又分为普通select模型,wsaasyncselect模型,wsaeventselect模型。我们将通过样例代码的方式逐一介绍。
  6 
  7 一、select模型
  8 
  9 使用该模型时,在服务端我们可以开辟两个线程,一个线程用来监听客户端的连接
 10 
 11 请求,另一个用来处理客户端的请求。主要用到的函数为select函数。如:
 12 
 13 全局变量:
 14 
 15 fd_set  g_fdClientSock;
 16 线程1处理函数:
 17 
 18 复制代码
 19     SOCKET listenSock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
 20 
 21     sockaddr_in sin;
 22     sin.sin_family = AF_INET;
 23     sin.sin_port = htons(7788);
 24     sin.sin_addr.S_un.S_addr = INADDR_ANY;
 25 
 26     int nRet = bind( listenSock, (sockaddr*)&sin, (int)(sizeof(sin)));
 27     if ( nRet == SOCKET_ERROR )
 28     {
 29         DWORD errCode = GetLastError();
 30         return;
 31     }
 32 
 33     listen( listenSock, 5);
 34 
 35     int clientNum = 0;
 36 
 37     sockaddr_in clientAddr;
 38 
 39     int nameLen = sizeof( clientAddr );
 40 
 41     while( clientNum < FD_SETSIZE )
 42     {
 43         SOCKET clientSock = accept( listenSock, (sockaddr*)&clientAddr, &nameLen );
 44         FD_SET( clientSock, &g_fdClientSock);
 45         clientNum++;
 46      }
 47 复制代码
 48 线程2处理函数:
 49 
 50 复制代码
 51     fd_set fdRead;
 52     FD_ZERO( &fdRead );
 53     int nRet = 0;
 54     char* recvBuffer =(char*)malloc( sizeof(char) * 1024 );
 55 
 56     if ( recvBuffer == NULL )
 57     {
 58         return;
 59     }
 60 
 61     memset( recvBuffer, 0, sizeof(char) * 1024 );
 62     while ( true )
 63     {
 64         fdRead = g_fdClientSock;
 65         nRet = select( 0, &fdRead, NULL, NULL, NULL );
 66         if ( nRet != SOCKET_ERROR )
 67         {
 68             for ( int i = 0; i < g_fdClientSock.fd_count; i++ )
 69             {
 70                 if ( FD_ISSET(g_fdClientSock.fd_array[i],&fdRead)  )
 71                 {
 72                     memset( recvBuffer, 0, sizeof(char) * 1024 );
 73                     nRet = recv( g_fdClientSock.fd_array[i], recvBuffer, 1024, 0);
 74                     if ( nRet == SOCKET_ERROR )
 75                     {
 76                         closesocket( g_fdClientSock.fd_array[i] );
 77                             FD_CLR( g_fdClientSock.fd_array[i], &g_fdClientSock );
 78                     }
 79                     else
 80                     {
 81                         //todo:后续处理
 82                        }
 83                 }
 84             }
 85         }
 86     }
 87 
 88     if ( recvBuffer != NULL )
 89     {
 90         free( recvBuffer );
 91     }
 92 复制代码
 93 该模型有个最大的缺点就是,它需要一个死循环不停的去遍历所有的客户端套接字集合,询问是否有数据到来,这样,如果连接的客户端很多,势必会影响处理客户端请求的效率,但它的优点就是解决了每一个客户端都去开辟新的线程与其通信的问题。如果有一个模型,可以不用去轮询客户端套接字集合,而是等待系统通知,当有客户端数据到来时,系统自动的通知我们的程序,这就解决了select模型带来的问题了。
 94 
 95 二、WsaAsyncSelect模型
 96 
 97 WsaAsyncSelect模型就是这样一个解决了普通select模型问题的socket编程模型。它是在有客户端数据到来时,系统发送消息给我们的程序,我们的程序只要定义好消息的处理方法就可以了,用到的函数只要是WSAAsyncSelect,如:
 98 
 99 首先,我们定义一个Windows消息,告诉系统,当有客户端数据到来时,发送该消息给我们。
100 
101 #define  UM_SOCK_ASYNCRECVMSG  WM_USER + 1
102 在我们的处理函数中可以如下监听客户端的连接:
103 
104 复制代码
105     SOCKET listenSock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
106     sockaddr_in sin;
107     sin.sin_family = AF_INET;
108     sin.sin_port = htons(7788);
109     sin.sin_addr.S_un.S_addr = INADDR_ANY;
110     int nRet = bind( listenSock, (sockaddr*)&sin, (int)(sizeof(sin)));
111     if ( nRet == SOCKET_ERROR )
112     {
113         DWORD errCode = GetLastError();
114         return;
115     }
116 
117     listen( listenSock, 5);
118 
119     int clientNum = 0;
120     sockaddr_in clientAddr;
121     int nameLen = sizeof( clientAddr );
122 
123     while( clientNum < FD_SETSIZE )
124     {
125         SOCKET clientSock = accept( listenSock, (sockaddr*)&clientAddr, &nameLen );
126         //hWnd为接收系统发送的消息的窗口句柄
127          WSAAsyncSelect( clientSock, hWnd, UM_SOCK_ASYNCRECVMSG, FD_READ | FD_CLOSE );
128         clientNum++;
129     }
130 复制代码
131  
132 
133 接下来,我们需要在我们的窗口添加对UM_SOCK_ASYNCRECVMSG消息的处理函数,在该函数中真正接收客户端发送过来的数据,在这个消息处理函数中的wparam参数表示的是客户端套接字,lparam参数表示的是发生的网络事件如:
134 
135 复制代码
136    SOCKET clientSock = (SOCKET)wParam;
137    if ( WSAGETSELECTERROR( lParam ) )
138    {
139       closesocket( clientSock );
140       return;
141    }
142 
143    switch ( WSAGETSELECTEVENT( lParam ) )
144    {
145        case FD_READ:
146        {
147            char recvBuffer[1024] = {'\0'};
148            int nRet = recv( clientSock, recvBuffer, 1024, 0 );
149            if ( nRet > 0 )
150            {
151                 szRecvMsg.AppendFormat(_T("Client %d Say:%s\r\n"), clientSock, recvBuffer );
152            }
153            else
154            {
155                 //client disconnect
156                 szRecvMsg.AppendFormat(_T("Client %d Disconnect!\r\n"), clientSock );
157            }
158         }                              
159 
160         break;
161 
162       case FD_CLOSE:
163       {
164            closesocket( clientSock );
165            szRecvMsg.AppendFormat(_T("Client %d Disconnect!\r\n"), clientSock );
166       }
167 
168       break;
169     }
170 复制代码
171     可以看到WsaAsyncSelect模型是非常简单的模型,它解决了普通select模型的问题,但是它最大的缺点就是它只能用在windows程序上,因为它需要一个接收系统消息的窗口句柄,那么有没有一个模型既可以解决select模型的问题,又不限定只能是windows程序才能用呢?下面我们来看看WsaEventSelect模型。
172 
173 三、WsaEventSelect模型
174 
175 WsaEventSelect模型是一个不用主动去轮询所有客户端套接字是否有数据到来的模型,它也是在客户端有数据到来时,系统发送通知给我们的程序,但是,它不是发送消息,而是通过事件的方式来通知我们的程序,这就解决了WsaAsyncSelect模型只能用在windows程序的问题。
176 
177 该模型的实现,我们也可以开辟两个线程来进行处理,一个用来接收客户端的连接请求,一个用来与客户端进行通信,用到的主要函数有WSAEventSelect,WSAWaitForMultipleEvents,WSAEnumNetworkEvents实现方式如下:
178 
179 首先定义三个全局数组
180 
181 SOCKET      g_SockArray[MAX_NUM_SOCKET];//存放客户端套接字
182 
183 WSAEVENT    g_EventArray[MAX_NUM_SOCKET];//存放该客户端有数据到来时,触发的事件
184 
185 UINT32      g_totalEvent = 0;//记录客户端的连接数
186 线程1处理函数如下:
187 
188 复制代码
189     SOCKET listenSock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
190     sockaddr_in sin;
191     sin.sin_family = AF_INET;
192     sin.sin_port = htons(7788);
193     sin.sin_addr.S_un.S_addr = INADDR_ANY;
194     int nRet = bind( listenSock, (sockaddr*)&sin, (int)(sizeof(sin)));
195     if ( nRet == SOCKET_ERROR )
196     {
197         DWORD errCode = GetLastError();
198         return199     }
200 
201     listen( listenSock, 5);
202 
203     sockaddr_in clientAddr;
204     int nameLen = sizeof( clientAddr );
205     while( g_totalEvent < MAX_NUM_SOCKET )
206     {
207         SOCKET clientSock = accept( listenSock, (sockaddr*)&clientAddr, &nameLen );
208         if ( clientSock == INVALID_SOCKET )
209         {
210             continue;
211         }
212         g_SockArray[g_totalEvent] = clientSock;
213 
214         if( (g_EventArray[g_totalEvent] = WSACreateEvent()) == WSA_INVALID_EVENT )
215         {
216             continue;
217         }
218 
219         WSAEventSelect( clientSock, g_EventArray[g_totalEvent],FD_READ | FD_CLOSE );
220         g_totalEvent++;
221     }
222 复制代码
223     线程2的处理函数如下:
224 
225 复制代码
226     int nIndex = 0;
227     char* recvBuffer =(char*)malloc( sizeof(char) * 1024 );
228 
229     if ( recvBuffer == NULL )
230     {
231     return;
232     }
233 
234     memset( recvBuffer, 0, sizeof(char) * 1024 );
235 
236     while( true )
237     {
238         nIndex = WSAWaitForMultipleEvents( g_totalEvent, g_EventArray, FALSE, WSA_INFINITE,FALSE );
239         if ( nIndex == WSA_WAIT_FAILED )
240         {
241             continue;
242         }
243         else
244         { 
245             WSAResetEvent( g_EventArray[ nIndex - WSA_WAIT_EVENT_0]);
246             SOCKET clientSock = g_SockArray[ nIndex - WSA_WAIT_EVENT_0 ];
247             WSANETWORKEVENTS wsaNetWorkEvent;
248 
249             int nRet = WSAEnumNetworkEvents( clientSock, g_EventArray[nIndex - WSA_WAIT_EVENT_0], &wsaNetWorkEvent );
250             if ( SOCKET_ERROR == nRet )
251             {
252                 continue;
253             }
254             else if ( wsaNetWorkEvent.lNetworkEvents & FD_READ )
255             {
256                 if ( wsaNetWorkEvent.iErrorCode[FD_READ_BIT] != 0 )
257                 {
258                     //occur error
259                     closesocket( clientSock );
260                 }
261                 else 
262                 {
263                     memset( recvBuffer, 0, sizeof(char) * 1024 );
264                     nRet = recv( clientSock, recvBuffer, 1024, 0);
265                     if ( nRet == SOCKET_ERROR )
266                     {
267                         closesocket( clientSock );
268                     }
269                     else
270                     {
271                         //todo:对接收到的客户端数据进行处理
272                         }
273                  }
274              }
275              else if( wsaNetWorkEvent.lNetworkEvents & FD_CLOSE )
276              {
277                 if ( wsaNetWorkEvent.iErrorCode[FD_CLOSE_BIT] != 0 )
278                 {
279                     //occur error
280                     closesocket( clientSock );
281                 }
282                 else
283                 {
284                     closesocket( clientSock );
285                 }  
286              }
287         }
288     }
289 
290     if ( recvBuffer != NULL )
291     {
292         free( recvBuffer );
293     }
294 复制代码
295  
296 
297      该模型通过一个死循环里面调用WSAWaitForMultipleEvents函数来等待客户端套接字对应的Event的到来,一旦事件通知到达,就通过该套接字去接收数据。虽然WsaEventSelect模型的实现较前两种方法复杂,但它在效率和兼容性方面是最好的。
298 
299     以上三种模型虽然在效率方面有了不少的提升,但它们都存在一个问题,就是都预设了只能接收64个客户端连接,虽然我们在实现时可以不受这个限制,但是那样,它们所带来的效率提升又将打折扣,那又有没有什么模型可以解决这个问题呢?我们的下一篇重叠I/0模型将解决这个问题
View Code

 5、为什么多线程能提高效率

1 对单CPU, 即采用多线程不会提高程序的执行速度,反而会降低速度,但是对于用户来说,可以减少用户的响应时间。
2 对于多CPU或者CPU采用超线程技术,能更高效的提高系统内多个程序间并发执行的程度。
3 Ps.注意线程并发问题,注意线程数量问题,并不是越多的线程效率越高!
View Code

6、tcp 流量控制方法

 1 1. 利用滑动窗口实现流量控制
 2 如果发送方把数据发送得过快,接收方可能会来不及接收,这就会造成数据的丢失。所谓流量控制就是让发送方的发送速率不要太快,要让接收方来得及接收。
 3 利用滑动窗口机制可以很方便地在TCP连接上实现对发送方的流量控制。
 4  设A向B发送数据。在连接建立时,B告诉了A:“我的接收窗口是rwnd = 400 ”(这里的rwnd表示 receiver window) 。因此,发送方的发送窗口不能超过接收方给出的接收窗口的数值。请注意,TCP的窗口单位是字节,不是报文段。TCP连接建立时的窗口协商过程在图中没有显示出来。再设每一个报文段为100字节长,而数据报文段序号的初始值设为1。大写ACK表示首部中的确认位ACK,小写ack表示确认字段的值ack。
 5 
 6     从图中可以看出,B进行了三次流量控制。第一次把窗口减少到rwnd = 300 ,第二次又减到了rwnd = 100 ,最后减到rwnd = 0 ,即不允许发送方再发送数据了。这种使发送方暂停发送的状态将持续到主机B重新发出一个新的窗口值为止。B向A发送的三个报文段都设置了 ACK = 1 ,只有在ACK=1时确认号字段才有意义。
 7     TCP为每一个连接设有一个持续计时器(persistence timer)。只要TCP连接的一方收到对方的零窗口通知,就启动持续计时器。若持续计时器设置的时间到期,就发送一个零窗口控测报文段(携1字节的数据),那么收到这个报文段的一方就重新设置持续计时器。
 8 2. 必须考虑传输速率
 9 可以用不同的机制来控制TCP报文段的发送时机。如:<1>. TCP维持一个变量,它等于最大报文段长度MSS。只要缓存中存放的数据达到MSS字节时,就组装成一个TCP报文段发送出去。<2>. 由发送方的应用进程指明要求发送报文段,即TCP支持的推送( push )操作。<3>. 发送方的一个计时器期限到了,这时就把已有的缓存数据装入报文段(但长度不能超过MSS)发送出去。
10     Nagle算法:若发送应用进程把要发送的数据逐个字节地送到TCP的发送缓存,则发送方就把第一个数据字节先发送出去,把后面到达的数据字节都缓存起来。当发送方接收对第一个数据字符的确认后,再把发送缓存中的所有数据组装成一个报文段再发送出去,同时继续对随后到达的数据进行缓存。只有在收到对前一个报文段的确认后才继续发送下一个报文段。当数据到达较快而网络速率较慢时,用这样的方法可明显地减少所用的网络带宽。Nagle算法还规定:当到达的数据已达到发送窗口大小的一半或已达到报文段的最大长度时,就立即发送一个报文段。
11 另,糊涂窗口综合证: TCP接收方的缓存已满,而交互式的应用进程一次只从接收缓存中读取1字节(这样就使接收缓存空间仅腾出1字节),然后向发送方发送确认,并把窗口设置为1个字节(但发送的数据报为40字节的的话)。接收,发送方又发来1个字节的数据(发送方的IP数据报是41字节)。接收方发回确认,仍然将窗口设置为1个字节。这样,网络的效率很低。要解决这个问题,可让接收方等待一段时间,使得或者接收缓存已有足够空间容纳一个最长的报文段,或者等到接收方缓存已有一半空闲的空间。只要出现这两种情况,接收方就发回确认报文,并向发送方通知当前的窗口大小。此外,发送方也不要发送太小的报文段,而是把数据报积累成足够大的报文段,或达到接收方缓存的空间的一半大小。
View Code

7、多线程并发问题  线程池

 1   互斥与同步
 2 互斥和同步是两个紧密相关而又容易混淆的概念。
 3 互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
 4 同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源,如“第一类读写者模型”。
 5 
 6  线程的同步
 7 线程间同步什么作用?解决线程并发的问题
 8 线程的同步方式;原子访问 关键段  互斥量  事件 信号量
 9 
10 1、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。在任意时刻只允许一个线程对共享资源进行访问,如果有多个线程试图访问公共资源,那么在有一个线程进入后,其他试图访问公共资源的线程将被挂起,并一直等到进入临界区的线程离开,临界区在被释放后,其他线程才可以抢占。 
11 2、互斥量:采用互斥对象机制。 只有拥有互斥对象的线程才有访问公共资源的权限,因为互斥对象只有一个,所以能保证公共资源不会同时被多个线程访问。互斥不仅能实现同一应用程序的公共资源安全共享,还能实现不同应用程序的公共资源安全共享 
12 3、信号量:它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目 
13 4、事 件: 通过通知操作的方式来保持线程的同步,还可以方便实现对多个线程的优先级比较的操作
14 线程池:
15 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务
16 
17 原理:
18 线程池是预先创建线程的一种技术。线程池在还没有任务到来之前,创建一定数量的线程,放入空闲队列中。这些线程都是处于睡眠状态,即均为启动,不消耗CPU,而只是占用较小的内存空间。当请求到来之后,缓冲池给这次请求分配一个空闲线程,把请求传入此线程中运行,进行处理。当预先创建的线程都处于运行状态,即预制线程不够,线程池可以自由创建一定数量的新线程,用于处理更多的请求。当系统比较闲的时候,也可以通过移除一部分一直处于停用状态的线程。
19 
20 简单线程池的设计
21 一个典型的线程池,应该包括如下几个部分:
22 1、线程池管理器(ThreadPool),用于启动、停用,管理线程池
23 2、工作线程(WorkThread),线程池中的线程
24 3、请求接口(WorkRequest),创建请求对象,以供工作线程调度任务的执行
25 4、请求队列(RequestQueue),用于存放和提取请求
26 5、结果队列(ResultQueue),用于存储请求执行后返回的结果
27 线程池的注意事项
28 虽然线程池是构建多线程应用程序的强大机制,但使用它并不是没有风险的。在使用线程池时需注意线程池大小与性能的关系,注意并发风险、死锁、资源不足和线程泄漏等问题。
291)线程池大小。多线程应用并非线程越多越好,需要根据系统运行的软硬件环境以及应用本身的特点决定线程池的大小。一般来说,如果代码结构合理的话,线程数目与CPU 数量相适合即可。如果线程运行时可能出现阻塞现象,可相应增加池的大小;如有必要可采用自适应算法来动态调整线程池的大小,以提高CPU 的有效利用率和系统的整体性能。
302)并发错误。多线程应用要特别注意并发错误,要从逻辑上保证程序的正确性,注意避免死锁现象的发生。
313)线程泄漏。这是线程池应用中一个严重的问题,当任务执行完毕而线程没能返回池中就会发生线程泄漏现象。
View Code

8、多线程多进程比较

 1 关于多进程和多线程,教科书上最经典的一句话是“进程是资源分配的最小单位,线程是CPU调度的最小单位”,这句话应付考试基本上够了,但如果在工作中遇到类似的选择问题,那就没有这么简单了,选的不好,会让你深受其害。
 2 经常在网络上看到有的XDJM问“多进程好还是多线程好?”、“Linux下用多进程还是多线程?”等等期望一劳永逸的问题,我只能说:没有最好,只有更好。根据实际情况来判断,哪个更加合适就是哪个好。
 3 我们按照多个不同的维度,来看看多线程和多进程的对比(注:因为是感性的比较,因此都是相对的,不是说一个好得不得了,另外一个差的无法忍受)。
 4 
 5 对比维度    多进程    多线程    总结
 6 数据共享、同步    数据共享复杂,需要用IPC;数据是分开的,同步简单    因为共享进程数据,数据共享简单,但也是因为这个原因导致同步复杂    各有优势
 7 内存、CPU    占用内存多,切换复杂,CPU利用率低    占用内存少,切换简单,CPU利用率高    线程占优
 8 创建销毁、切换    创建销毁、切换复杂,速度慢    创建销毁、切换简单,速度很快    线程占优
 9 编程、调试    编程简单,调试简单    编程复杂,调试复杂    进程占优
10 可靠性    进程间不会互相影响    一个线程挂掉将导致整个进程挂掉    进程占优
11 分布式    适应于多核、多机分布式;如果一台机器不够,扩展到多台机器比较简单    适应于多核分布式    进程占优
12 1)需要频繁创建销毁的优先用线程
13 原因请看上面的对比。
14 这种原则最常见的应用就是Web服务器了,来一个连接建立一个线程,断了就销毁线程,要是用进程,创建和销毁的代价是很难承受的
15 2)需要进行大量计算的优先使用线程
16 所谓大量计算,当然就是要耗费很多CPU,切换频繁了,这种情况下线程是最合适的。
17 这种原则最常见的是图像处理、算法处理。
18 3)强相关的处理用线程,弱相关的处理用进程
19 什么叫强相关、弱相关?理论上很难定义,给个简单的例子就明白了。
20 一般的Server需要完成如下任务:消息收发、消息处理。“消息收发”和“消息处理”就是弱相关的任务,而“消息处理”里面可能又分为“消息解码”、“业务处理”,这两个任务相对来说相关性就要强多了。因此“消息收发”和“消息处理”可以分进程设计,“消息解码”、“业务处理”可以分线程设计。
21 当然这种划分方式不是一成不变的,也可以根据实际情况进行调整。
22 4)可能要扩展到多机分布的用进程,多核分布的用线程
23 原因请看上面对比。
24 5)都满足需求的情况下,用你最熟悉、最拿手的方式
25 至于“数据共享、同步”、“编程、调试”、“可靠性”这几个维度的所谓的“复杂、简单”应该怎么取舍,我只能说:没有明确的选择方法。但我可以告诉你一个选择原则:如果多进程和多线程都能够满足要求,那么选择你最熟悉、最拿手的那个。 
26 需要提醒的是:虽然我给了这么多的选择原则,但实际应用中基本上都是“进程+线程”的结合方式,千万不要真的陷入一种非此即彼的误区。
27 消耗资源:
28 从内核的观点看,进程的目的就是担当分配系统资源(CPU时间、内存等)的基本单位。线程是进程的一个执行流,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。
29 线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而且,线程间彼此切换所需的时间也远远小于进程间切换所需要的时间。据统计,总的说来,一个进程的开销大约是一个线程开销的30倍左右,当然,在具体的系统上,这个数据可能会有较大的区别。
30 通讯方式:
31 进程之间传递数据只能是通过通讯的方式,即费时又不方便。线程时间数据大部分共享(线程函数内部不共享),快捷方便。但是数据同步需要锁对于static变量尤其注意
32 线程自身优势:
33 提高应用程序响应;使多CPU系统更加有效。操作系统会保证当线程数不大于CPU数目时,不同的线程运行于不同的CPU上;
34 改善程序结构。一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改。
View Code

 9、进程创建的过程:

1 1,申请空白PCB(进程控制块);
2 
3 2,为新进程分派资源;
4 
5 3,初始化PCB;
6 
7 4,将新进程插入就绪队列;
View Code
11)进程标识符(内部,外部)
22)处理机的信息(通用寄存器,指令计数器,PSW,用户的栈指针)。
33)进程调度信息(进程状态,进程的优先级,进程调度所需的其它信息,事件)
44)进程控制信息(程序的数据的地址,资源清单,进程同步和通信机制,链接指针)
View Code
1 1. 发生中断——save cs:eip/esp/eflags(current) to kernel stack, then load cs:eip(entry of a specific ISR) and ss:esp(point to kernel stack).
2 3. SAVE_ALL //保存现场,这里是已经进入内核中断处里过程
3 4. 中断处理过程中或中断返回前调用了schedule(),其中的switch_to做了关键的进程上下文切换
4 5. 标号1之后开始运行用户态进程Y(这里Y曾经通过以上步骤被切换出去过因此可以从标号1继续执行)
5 6. restore_all //恢复现场
6 7. iret - pop cs:eip/ss:esp/eflags from kernel stack
7 8. 继续运行用户态进程X
进程切换过程
1 1、信号量
2 2、临界区
3 3、时间
4 4、互斥量
线程同步方式

10、僵尸进程

 1 1. 产生原因:
 2     在UNIX 系统中,一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他,那么他将变成一个僵尸进程。通过ps命令查看其带有defunct的标志。僵尸进程是一个早已死亡的进程,但在进程表 (processs table)中仍占了一个位置(slot)。
 3     但是如果该进程的父进程已经先结束了,那么该进程就不会变成僵尸进程。因为每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程,看看有没有哪个 进程是刚刚结束的这个进程的子进程,如果是的话,就由Init进程来接管他,成为他的父进程,从而保证每个进程都会有一个父进程。而Init进程会自动 wait其子进程,因此被Init接管的所有进程都不会变成僵尸进程。
 4     2. 原理分析:
 5     每个Unix进程在进程表里都有一个进入点(entry),核心进程执 行该进程时使用到的一切信息都存储在进入点。当用 ps 命令察看系统中的进程信息时,看到的就是进程表中的相关数据。当以fork()系统调用建立一个新的进程后,核心进程就会在进程表中给这个新进程分配一个 进入点,然后将相关信息存储在该进入点所对应的进程表内。这些信息中有一项是其父进程的识别码。
 6     子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程到底什么时候结束。那么会不会因为父进程太忙来不及 wait 子进程,或者说不知道子进程什么时候结束,而丢失子进程结束时的状态信息呢?不会。因为UNIX提供了一种机制可以保证,只要父进程想知道子进程结束时的 状态信息,就可以得到。这种机制就是:当子进程走完了自己的生命周期后,它会执行exit()系统调用,内核释放该进程所有的资源,包括打开的文件,占用 的内存等。但是仍然为其保留一定的信息(包括进程号the process ID,退出码exit code,退出状态the terminationstatus of the process,运行时间the amount of CPU time taken by the process等),这些数据会一直保留到系统将它传递给它的父进程为止,直到父进程通过wait / waitpid来取时才释放。
 7     3.解决方法:
 81) 父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起。
 9     执行wait()或waitpid()系统调用,则子进程在终止后会立即把它在进程表中的数据返回给父进程,此时系统会立即删除该进入点。在这种情形下就不会产生defunct进程。
102) 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler。在子进程结束后,父进程会收到该信号,可以在handler中调用wait回收。
113) 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCLD, SIG_IGN)或signal(SIGCHLD, SIG_IGN)通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收,并不再给父进程发送信号
124)fork两次,父进程fork一个子进程,然后继续工作,子进程fork一个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进程的回收还要自己做。
View Code

 

 

 

 

 

 

3、ios七层

  1 OSI七层模型介绍
  2 OSI是一个开放性的通行系统互连参考模型,他是一个定义的非常好的协议规范。OSI模型有7层结构,每层都可以有几个子层。下面我简单的介绍一下这7层及其功能。
  3 
  4 OSI的7层从上到下分别是
  5 
  6 7 应用层 
  7 6 表示层
  8 5 会话层
  9 4 传输层
 10 3 网络层
 11 2 数据链路层
 12 1 物理层
 13 
 14 其中高层,既7、65、4层定义了应用程序的功能,下面3层,既3、2、1层主要面向通过网络的端到端的数据流。下面我给大家介绍一下这7层的功能:
 15 
 161)应用层:与其他计算机进行通讯的一个应用,它是对应应用程序的通信服务的。例如,一个没有通信功能的字处理程序就不能执行通信的代码,从事字处理工作的程序员也不关心OSI的第7层。但是,如果添加了一个传输文件的选项,那么字处理器的程序员就需要实现OSI的第7层。示例:telnet,HTTP,FTP,WWW,NFS,SMTP等。
 17 
 182)表示层:这一层的主要功能是定义数据格式及加密。例如,FTP允许你选择以二进制或ASII格式传输。如果选择二进制,那么发送方和接收方不改变文件的内容。如果选择ASII格式,发送方将把文本从发送方的字符集转换成标准的ASII后发送数据。在接收方将标准的ASII转换成接收方计算机的字符集。示例:加密,ASII等。
 19 
 203)会话层:他定义了如何开始、控制和结束一个会话,包括对多个双向小时的控制和管理,以便在只完成连续消息的一部分时可以通知应用,从而使表示层看到的数据是连续的,在某些情况下,如果表示层收到了所有的数据,则用数据代表表示层。示例:RPC,SQL等。
 21 
 224)传输层:这层的功能包括是否选择差错恢复协议还是无差错恢复协议,及在同一主机上对不同应用的数据流的输入进行复用,还包括对收到的顺序不对的数据包的重新排序功能。示例:TCP,UDP,SPX。
 23 
 245)网络层:这层对端到端的包传输进行定义,他定义了能够标识所有结点的逻辑地址,还定义了路由实现的方式和学习的方式。为了适应最大传输单元长度小于包长度的传输介质,网络层还定义了如何将一个包分解成更小的包的分段方法。示例:IP,IPX等。
 25 
 266)数据链路层:他定义了在单个链路上如何传输数据。这些协议与被讨论的歌种介质有关。示例:ATM,FDDI等。
 27 
 287)物理层:OSI的物理层规范是有关传输介质的特性标准,这些规范通常也参考了其他组织制定的标准。连接头、针、针的使用、电流、电流、编码及光调制等都属于各种物理层规范中的内容。物理层常用多个规范完成对所有细节的定义。示例:Rj45,802.3等。
 29 
 30 OSI分层的优点:
 31 
 321)人们可以很容易的讨论和学习协议的规范细节。
 33 
 342)层间的标准接口方便了工程模块化。
 35 
 363)创建了一个更好的互连环境。
 37 
 384)降低了复杂度,使程序更容易修改,产品开发的速度更快。
 39 
 405)每层利用紧邻的下层服务,更容易记住个层的功能。
 41 
 42 大多数的计算机网络都采用层次式结构,即将一个计算机网络分为若干层次,处在高层次的系统仅是利用较低层次的系统提供的接口和功能,不需了解低层实现该功能所采用的算法和协议;较低层次也仅是使用从高层系统传送来的参数,这就是层次间的无关性。因为有了这种无关性,层次间的每个模块可以用一个新的模块取代,只要新的模块与旧的模块具有相同的功能和接口,即使它们使用的算法和协议都不一样。
 43 
 44 网络中的计算机与终端间要想正确的传送信息和数据,必须在数据传输的顺序、数据的格式及内容等方面有一个约定或规则,这种约定或规则称做协议。网络协议主要有三个组成部分:
 45 
 46 1、语义:
 47 
 48 是对协议元素的含义进行解释,不同类型的协议元素所规定的语义是不同的。例如需要发出何种控制信息、完成何种动作及得到的响应等。
 49 
 50 2、语法:
 51 
 52 将若干个协议元素和数据组合在一起用来表达一个完整的内容所应遵循的格式,也就是对信息的数据结构做一种规定。例如用户数据与控制信息的结构与格式等。
 53 
 54 3、时序:
 55 
 56 对事件实现顺序的详细说明。例如在双方进行通信时,发送点发出一个数据报文,如果目标点正确收到,则回答源点接收正确;若接收到错误的信息,则要求源点重发一次。
 57 
 58 70年代以来,国外一些主要计算机生产厂家先后推出了各自的网络体系结构,但它们都属于专用的。
 59 为使不同计算机厂家的计算机能够互相通信,以便在更大的范围内建立计算机网络,有必要建立一个国际范围的网络体系结构标准。
 60 
 61 国际标准化组织ISO 于1981年正式推荐了一个网络系统结构----七层参考模型,叫做开放系统互连模型(Open System Interconnection,OSI)。由于这个标准模型的建立,使得各种计算机网络向它靠  拢, 大大推动了网络通信的发展。
 62 
 63 OSI 参考模型将整个网络通信的功能划分为七个层次,见图1。它们由低到高分别是物理层(PH)、链路层(DL)、网络层(N)、传输层(T)、会议层(S)、表示层(P)、应用层(A)。每层完成一定的功能,每层都直接为其上层提供服务,并且所有层次都互相支持。第四层到第七层主要负责互操作性,而一层到三层则用于创造两个网络设备间的物理连接.
 64 
 65 1.物理层
 66 
 67 物理层是OSI的第一层,它虽然处于最底层,却是整个开放系统的基础。物理层为设备之间的数据通信提供传输媒体及互连设备,为数据传输提供可靠的环境。
 68 
 69 1.1媒体和互连设备
 70 
 71 物理层的媒体包括架空明线、平衡电缆、光纤、无线信道等。通信用的互连设备指DTE和DCE间的互连设备。DTE既数据终端设备,又称物理设备,如计算机、终端等都包括在内。而DCE则是数据通信设备或电路连接设备,如调制解调器等。数据传输通常是经过DTE——DCE,再经过DCE——DTE的路径。互连设备指将DTE、DCE连接起来的装置,如各种插头、插座。LAN中的各种粗、细同轴电缆、T型接、插头,接收器,发送器,中继器等都属物理层的媒体和连接器。 
 72 
 73 1.2物理层的主要功能
 74 
 75 1.2.1为数据端设备提供传送数据的通路,数据通路可以是一个物理媒体,也可以是多个物理媒体连接而成.一次完整的数据传输,包括激活物理连接,传送数据,终止物理连接.所谓激活,就是不管有多少物理媒体参与,都要在通信的两个数据终端设备间连接起来,形成一条通路. 
 76 
 77 1.2.2传输数据.物理层要形成适合数据传输需要的实体,为数据传送服务.一是要保证数据能在其上正确通过,二是要提供足够的带宽(带宽是指每秒钟内能通过的比特(BIT)数),以减少信道上的拥塞.传输数据的方式能满足点到点,一点到多点,串行或并行,半双工或全双工,同步或异步传输的需要. 
 78 
 79 1.3物理层的一些重要标准
 80 
 81 物理层的一些标准和协议早在OSI/TC97/C16 分技术委员会成立之前就已制定并在应用了,OSI也制定了一些标准并采用了一些已有的成果.下面将一些重要的标准列出,以便读者查阅.ISO2110:称为"数据通信----25芯DTE/DCE接口连接器和插针分配".它与EIA(美国电子工
 82 业协会)的"RS-232-C"基本兼容。ISO2593:称为"数据通信----34芯DTE/DCE----接口连接器和插针分配"。ISO4092:称为"数据通信----37芯DTE/DEC----接口连接器和插针分配".与EIARS-449兼容。CCITT V.24:称为"数据终端设备(DTE)和数据电路终接设备之间的接口电路定义表".其功能与EIARS-232-C及RS-449兼容于100序列线上. 
 83 
 84 2.数据链路层
 85 
 86 数据链路可以粗略地理解为数据通道。物理层要为终端设备间的数据通信提供传输媒体及其连接.媒体是长期的,连接是有生存期的.在连接生存期内,收发两端可以进行不等的一次或多次数据通信.每次通信都要经过建立通信联络和拆除通信联络两过程.这种建立起来的数据收发关系就叫作数据链路.而在物理媒体上传输的数据难免受到各种不可靠因素的影响而产生差错,为了弥补物理层上的不足,为上层提供无差错的数据传输,就要能对数据进行检错和纠错.数据链路的建立,拆除,对数据的检错,纠错是数据链路层的基本任务。 
 87 
 88 2.1链路层的主要功能
 89 
 90 链路层是为网络层提供数据传送服务的,这种服务要依靠本层具备的功能来实现。链路层应具备如下功能:
 91 
 92 2.1.1链路连接的建立,拆除,分离。 
 93 
 94 2.1.2帧定界和帧同步。链路层的数据传输单元是帧,协议不同,帧的长短和界面也有差别,但无论如何必须对帧进行定界。 
 95 
 96 2.1.3顺序控制,指对帧的收发顺序的控制。
 97 
 98 2.1.4差错检测和恢复。还有链路标识,流量控制等等.差错检测多用方阵码校验和循环码校验来检测信道上数据的误码,而帧丢失等用序号检测.各种错误的恢复则常靠反馈重发技术来完成。
 99 
100 2.2数据链路层的主要协议
101 
102 数据链路层协议是为发对等实体间保持一致而制定的,也为了顺利完成对网络层的服务。主要协议如下:
103 
104 2.2.1ISO1745--1975:"数据通信系统的基本型控制规程".这是一种面向字符的标准,利用10个控制字符完成链路的建立,拆除及数据交换.对帧的收发情况及差错恢复也是靠这些字符来完成.ISO1155, ISO1177, ISO2626, ISO2629等标准的配合使用可形成多种链路控制和数据传输方式. 
105 
106 2.2.2ISO3309--1984:称为"HDLC 帧结构".ISO4335--1984:称为"HDLC 规程要素 ".ISO7809--1984:称为"HDLC 规程类型汇编".这3个标准都是为面向比特的数据传输控制而制定的.有人习惯上把这3个标准组合称为高级链路控制规程. 
107 
108 2.2.3ISO7776:称为"DTE数据链路层规程".与CCITT X.25LAB"平衡型链路访问规程"相兼容.
109 
110 2.3链路层产品
111 
112 独立的链路产品中最常见的当属网卡,网桥也是链路产品。MODEM的某些功能有人认为属于链路层,对些还有争议.数据链路层将本质上不可靠的传输媒体变成可靠的传输通路提供给网络层。在IEEE802.3情况下,数据链路层分成了两个子层,一个是逻辑链路控制,另一个是媒体访问控制。下图所示为IEEE802.3LAN体系结构。 
113 
114 AUI=连接单元接口 PMA=物理媒体连接
115 MAU=媒体连接单元 PLS=物理信令
116 MDI=媒体相关接口 
117 
118 3.网络层
119 
120 网络层的产生也是网络发展的结果.在联机系统和线路交换的环境中,网络层的功能没有太大意义.当数据终端增多时.它们之间有中继设备相连.此时会出现一台终端要求不只是与唯一的一台而是能和多台终端通信的情况,这就是产生了把任意两台数据终端设备的数据链接起来的问题,也就是路由或者叫寻径.另外,当一条物理信道建立之后,被一对用户使用,往往有许多空闲时间被浪费掉.人们自然会希望让多对用户共用一条链路,为解决这一问题就出现了逻辑信道技术和虚拟电路技术. 
121 
122 3.1网络层主要功能
123 
124 网络层为建立网络连接和为上层提供服务,应具备以下主要功能:
125 
126 3.1.1路由选择和中继. 
127 
128 3.1.2激活,终止网络连接. 
129 
130 3.1.3在一条数据链路上复用多条网络连接,多采取分时复用技术 .
131 
132 3.1.4差错检测与恢复. 
133 
134 3.1.5排序,流量控制. 
135 
136 3.1.6服务选择. 
137 
138 3.1.7网络管理. 
139 
140 3.2网络层标准简介
141 
142 网络层的一些主要标准如下:
143 
144 3.2.1 ISO.DIS8208:称为"DTE用的X.25分组级协议" 
145 
146 3.2.2 ISO.DIS8348:称为"CO 网络服务定义"(面向连接) 
147 
148 3.2.3 ISO.DIS8349:称为"CL 网络服务定义"(面向无连接) 
149 
150 3.2.4 ISO.DIS8473:称为"CL 网络协议" 
151 
152 3.2.5 ISO.DIS8348:称为"网络层寻址" 
153 
154 3.2.6 除上述标准外,还有许多标准。这些标准都只是解决网络层的部分功能,所以往往需要在网络层中同时使用几个标准才能完成整个网络层的功能.由于面对的网络不同,网络层将会采用不同的标准组合. 
155 
156 在具有开放特性的网络中的数据终端设备,都要配置网络层的功能.现在市场上销售的网络硬设备主要有网关和路由器.
157 
158 4.传输层
159 
160 传输层是两台计算机经过网络进行数据通信时,第一个端到端的层次,具有缓冲作用。当网络层服务质量不能满足要求时,它将服务加以提高,以满足高层的要求;当网络层服务质量较好时,它只用很少的工作。传输层还可进行复用,即在一个网络连接上创建多个逻辑连接。 传输层也称为运输层.传输层只存在于端开放系统中,是介于低3层通信子网系统和高3层之间的一层,但是很重要的一层.因为它是源端到目的端对数据传送进行控制从低到高的最后一层.
161 
162 有一个既存事实,即世界上各种通信子网在性能上存在着很大差异.例如电话交换网,分组交换网,公用数据交换网,局域网等通信子网都可互连,但它们提供的吞吐量,传输速率,数据延迟通信费用各不相同.对于会话层来说,却要求有一性能恒定的界面.传输层就承担了这一功能.它采用分流/合流,复用/介复用技术来调节上述通信子网的差异,使会话层感受不到.
163 
164 此外传输层还要具备差错恢复,流量控制等功能,以此对会话层屏蔽通信子网在这些方面的细节与差异.传输层面对的数据对象已不是网络地址和主机地址,而是和会话层的界面端口.上述功能的最终目的是为会话提供可靠的,无误的数据传输.传输层的服务一般要经历传输连接建立阶段,数据传送阶段,传输连接释放阶段3个阶段才算完成一个完整的服务过程.而在数据传送阶段又分为一般数据传送和加速数据传送两种。传输层服务分成5种类型.基本可以满足对传送质量,传送速度,传送费用的各种不同需要.传输层的协议标准有以下几种: 
165 
166 4.1 ISO8072:称为"面向连接的传输服务定义" 
167 
168 4.2 ISO8072:称为"面向连接的传输协议规范" 
169 
170 5.会话层
171 会话层提供的服务可使应用建立和维持会话,并能使会话获得同步。会话层使用校验点可使通信会话在通信失效时从校验点继续恢复通信。这种能力对于传送大的文件极为重要。会话层,表示层,应用层构成开放系统的高3层,面对应用进程提供分布处理,对话管理,信息表示,恢复最后的差错等. 
172 
173 会话层同样要担负应用进程服务要求,而运输层不能完成的那部分工作,给运输层功能差距以弥补.主要的功能是对话管理,数据流同步和重新同步。要完成这些功能,需要由大量的服务单元功能组合,已经制定的功能单元已有几十种.现将会话层主要功能介绍如下. 
174 
175 5.1为会话实体间建立连接。为给两个对等会话服务用户建立一个会话连接,应该做如下几项工作:
176 
177 5.1.1将会话地址映射为运输地址 
178 
179 5.1.2选择需要的运输服务质量参数(QOS) 
180 
181 5.1.3对会话参数进行协商 
182 
183 5.1.3识别各个会话连接 
184 
185 5.1.4传送有限的透明用户数据 
186 
187 5.2数据传输阶段
188 
189 这个阶段是在两个会话用户之间实现有组织的,同步的数据传输.用户数据单元为SSDU,而协议数据单元为SPDU.会话用户之间的数据传送过程是将SSDU转变成SPDU进行的. 
190 
191 5.3连接释放
192 
193 连接释放是通过"有序释放","废弃""有限量透明用户数据传送"等功能单元来释放会话连接的.会话层标准为了使会话连接建立阶段能进行功能协商,也为了便于其它国际标准参考和引用,定义了12种功能单元.各个系统可根据自身情况和需要,以核心功能服务单元为基础,选配其他功能单元组成合理的会话服务子集.会话层的主要标准有"DIS8236:会话服务定义""DIS8237:会话协议规范". 
194 
195 6.表示层
196 
197 表示层的作用之一是为异种机通信提供一种公共语言,以便能进行互操作。这种类型的服务之所以需要,是因为不同的计算机体系结构使用的数据表示法不同。例如,IBM主机使用EBCDIC编码,而大部分PC机使用的是ASCII码。在这种情况下,便需要会话层来完成这种转换。 
198 
199 通过前面的介绍,我们可以看出,会话层以下5层完成了端到端的数据传送,并且是可靠,无差错的传送.但是数据传送只是手段而不是目的,最终是要实现对数据的使用.由于各种系统对数据的定义并不完全相同,最易明白的例子是键盘,其上的某些键的含义在许多系统中都有差异.这自然给利用其它系统的数据造成了障碍.表示层和应用层就担负了消除这种障碍的任务.
200 
201 对于用户数据来说,可以从两个侧面来分析,一个是数据含义被称为语义,另一个是数据的表示形式,称做语法.像文字,图形,声音,文种,压缩,加密等都属于语法范畴.表示层设计了3类15种功能单位,其中上下文管理功能单位就是沟通用户间的数据编码规则,以便双方有一致的数据形式,能够互相认识.ISO表示层为服务,协议,文本通信符制定了DP8822,DP8823,DIS6937/2等一系列标准.
202 
203 7.应用层
204 
205 应用层向应用程序提供服务,这些服务按其向应用程序提供的特性分成组,并称为服务元素。有些可为多种应用程序共同使用,有些则为较少的一类应用程序使用。应用层是开放系统的最高层,是直接为应用进程提供服务的。其作用是在实现多个系统应用进程相互通信的同时,完成一系列业务处理所需的服务.其服务元素分为两类:公共应用服务元素CASE和特定应用服务元素SASE.CASE提供最基本的服务,它成为应用层中任何用户和任何服务元素的用户,主要为应用进程通信,分布系统实现提供基本的控制机制.特定服务SASE则要满足一些特定服务,如文卷传送,访问管理,作业传送,银行事务,订单输入等.
206 
207 这些将涉及到虚拟终端,作业传送与操作,文卷传送及访问管理,远程数据库访问,图形核心系统,开放系统互连管理等等.应用层的标准有DP8649"公共应用服务元素",DP8650"公共应用服务元素用协议",文件传送,访问和管理服务及协议.
208 
209 讨论:OSI七层模型是一个理论模型,实际应用则千变万化,因此更多把它作为分析、评判各种网络技术的依据;对大多数应用来说,只将它的协议族(即协议堆栈)与七层模型作大致的对应,看看实际用到的特定协议是属于七层中某个子层,还是包括了上下多层的功能。
210 
211 这样分层的好处有:
212 
213 1.使人们容易探讨和理解协议的许多细节。
214 
215 2.在各层间标准化接口,允许不同的产品只提供各层功能的一部分,(如路由器在一到三层),或者只提供协议功能的一部分。(如Win95中的Microsoft TCP/IP)
216 
217 3. 创建更好集成的环境。
218 
219 4. 减少复杂性,允许更容易编程改变或快速评估。
220 
221 5. 用各层的headers和trailers排错。
222 
223 6.较低的层为较高的层提供服务。
224 
225 7. 把复杂的网络划分成为更容易管理的层。
View Code

转载于:https://www.cnblogs.com/zhanzhao/p/5840079.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值