Linux多线程编程
Linux多线程编程
创建线程和结束线程
读取和设置线程属性
POSIX线程同步方式:POSIX信号量、互斥锁和条件变量
Linux线程概述线程模型线程是程序中完成一个独立任务的完整执行序列,即一个可调度实体。根据运行环境和调度者的身份,线程可分为内核线程和用户线程。内核线程在有的系统上也称为LWP(轻量级线程),运行在内核空间,由内核调度。用户线程运行在用户空间,由线程库来调度。当进程的一个内核线程获得CPU的使用权时,它就加载并运行一个用户线程。可见,内核线程相当于用户线程运行的容器。一个进程可以拥有M个内核线程和N个用户线程,其中M≤N。并且在一个系统的所有进程中,M和N的比值都是固定的。按照M:N的取值,线程的实现方式可分为三种模式:
完全在用户空间实现
完全由内和调度
双层调度
完全在用户空间实现的线程无需内核的支持,内核甚至根本不知道这些线程的存在。线程库负责管理所有执行线程,比如线程的优先级、时间片等。线程库利用longjmp来切换线程的执行,使它们看起来像是并发执行的。但实际上内核仍然是把整个进程作为最小单位来调度的。换句话说,一个进程的所有执行线程共享该进 ...
Linux多进程编程
多进程编程进程进程的概念一个程序文件, 只是一堆待执行的代码和部分待处理的数据它们只有被加载到内存中,然后让CPU逐条执行其代码,根据代码做出相应的动作,才形成一个真正“活的”、动态的 进程(Process)因此, 进程是一个动态变化的过程,是一出有始有终的戏而程序文件只是这一系列动作的原始蓝本,是一个静态的剧本
进程就是程序在内存中 动态执行的过程
进程是系统资源管理的 最小的单位
进程是动态的概念, 创建—运行–消亡
每个进程有 4G独立的进程空间,其中0-3G是用户空间,3G-4G是内核空间。 每个进程也有4G地址空间的,仅仅是地址空间,不是实际的内存,需要使用时向系统申请
进程是独立可调度的任务,绝大多数的操作系统都支持多进程
Linux中的三个特殊进程Linux中的进程都是由其它进程启动。如果进程a启动了进程b, 所以称a是b的父进程, b是a的子进程
Linux下有3个特殊的进程,idle进程(PID = 0), init进程(PID = 1)和kthreadd(PID = 2)
idle进程由系统自动创建, 运行在内核态
idle进程 ...
select应用——非阻塞connect
非阻塞connectTCP连接的建立涉及到一个三次握手的过程,且SOCKET中connect函数需要一直等到客户接收到对于自己的SYN的ACK为止才返回,这意味着每个connect函数总会阻塞其调用进程至少一个到服务器的RTT时间,而RTT波动范围很大,从局域网的几个毫秒到几百个毫秒甚至广域网上的几秒。这段时间内,我们可以执行其他处理工作,以便做到并行。在此,需要用到非阻塞connect。
非阻塞connect的作用:
可以让三路握手的处理等同与一般数据的处理,而不是一直让 connect一直尝试重连或者花费一个RTT时间。而且RTT时间从几毫秒到几秒不等,万一有许多连接,不论是尝试重连还是花费一个RTT时间,都将是致命的延时。
可以使用该技术同时建立多个连接。Web浏览器中常用。
既然使用select等待连接的建立,我们就可以制定一个时间限制,使得我们能够缩短connect的超时。
使用selcet与非阻塞connect的一些注意事项:
处理connect立即建立的情况。(比如我们连接的是同一个主机时)
当连接建立成功时,套接口描述符变成可写;
当一个套接口出错时,它会被 sele ...
poll应用——聊天室程序
一个简易聊天室程序
很多服务器要一边处理网络连接一边处理用户输入,比如聊天室程序,这样的就可以用I/O复用来实现,我们以一个poll实现的聊天室程序来举例说明一下
客户端程序12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879#include"head.h"#define _GNU_SOURCE 1using namespace std;#define BUFFER_SIZE 64/*很多服务器要一边处理网络连接一边处理用户输入,比如聊天室程序,这样的就可以用I/O复用来实现,我们以一个poll实现的聊天室程序来举例说明一下:*/int main(int argc, char** argv) { if(argc <= 2) { printf("usage: % ...
IO复用
IO复用
迅速看原理,勇敢看源码
select系统调用作用:
在一段指定时间内,监听用户感兴趣的文件描述符的可读、可写和异常等事件。
原型:
12#include <sys/select.h>int select ( int nfds, fd_set* readfds, fde_set* writefds, fd_set* exceptfds, struct timeval* timeout );
函数说明:
nfds: 指定被监听的文件描述符的总数,通常为所有文件描述符中的最大值+1
readfds、writefds 、exceptfds: 可读、可写和异常等事件对应的文件描述符集合。
fd_set结构:仅包含一个整型数组,该数组的每个元素的每一位标记了一个文件描述符。fd_set能容纳的文件描述符数量由FD_SETSIZE指定,这就限制了select能同时处理的文件描述符的总量。
select中的fd_set集合容量的限制为FD_SETSIZE,一般为1024 。修改它,需要重新编译内核。
fd_set相关的位操作:
123456789101112# ...
定时器
定时器
Linux 3种定时方法
socket 选项 SO_RCVTIMEO 和 SO_SNDTIMEO分别用来设置 socket 接收数据超时时间和发送数据超时时间。因此,这2个选项仅对数据的接收和发送相关的 socket 专用的系统调用有效。
SIGALRM 信号基于升序链表的定时器处理非活动连接
IO 复用系统调用的超时参数Linux 下的3组 IO 系统调用都带有超时参数,因此它们不仅能统一处理信号和IO事件,也能统一处理定时事件。但是由于IO复用函数系统调用可能在超时时间到期之前就返回(有IO事件发生),如果我们要利用它们来定时,就需要不断更新定时参数以反映剩余的时间。
定时器通常至少包含2个成员:
一个是超时时间(相对时间或者绝对时间)
一个任务回调函数
还可能包括回调函数需要的参数 以及是否重启定时器等信息
两种高效的管理定时器的容器:
时间轮固定的频率调用心博函数 tick, 并以此检查到期的定时器,然后执行定时器上的回调函数。
时间堆 将所有定时器中超时时间最小的一个定时器的超时时间作为心博间隔。
socket ...
Linux高性能服务器编程
Linux高性能服务器编程Linux网络编程基础API
探讨Linux网络编程基础与内核中TCP/IP协议族之间的关系,并为后续章节提供编程基础
从三方面来讨论Linux网络API
socket地址API,socket最开始的含义是一个IP地址和端口对,它唯一的标识了TCP通信的一端
socket基础API,socket的主要的API都定义在 sys/socket.h头文件中
网络信息API,Linux提供了一套网络信息的API,以实现主机名与IP地址,服务名与端口号之间的转换
socket地址API
0.字节序在了解socket地址API之前我们应该先了解一下字节序:
字节序的分类
大端字节序(big endian)
大端字节序是指一个整数的高位字节(23-31bit)存储在内存的低地址处,低位字节(0~7bit)存储在内存的高地址处.
小端字节序(little endian)
小端字节序则是指整数的高位字节存储在内存的高地址处,而低位字节则存储在内存的低地址处.
主机字节序和网络字节序
现代PC大多采用小端字节序,因 ...
python中的各项问题
python中的各项问题
Python内置类属性
__dict__ : 类的属性(包含一个字典,由类的数据属性组成)
__doc__ :类的文档字符串
__name__: 类名
__module__: 类定义所在的模块(类的全名是__main__.className,如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)
__bases__ : 类的所有父类构成元素(包含了一个由所有父类组成的元组)
python 基础重载方法
序号
方法, 描述 & 简单的调用
1
__init__ ( self [,args…] ) 构造函数 简单的调用方法: obj = className(args)
2
__del__( self ) 析构方法, 删除一个对象 简单的调用方法 : del obj
3
__repr__( self ) 转化为供解释器读取的形式 简单的调用方法 : repr(obj)
4
__str__( self ) 用于将值转化为适于人阅读的形式 简单的调用方法 : str(obj)
...
Hello MyBlog
hello MyBlog这是我第一次建立自己的博客网站,用于记录自己的成长,希望能在此处能留下些什么吧
无论在哪一个网站上,都很难舒展自己(社恐?),可能是有人的地方都没有办法
所以我想找一个只属于自己的地方,那就是这里