10月24日晚上,回到宿舍准备写这周的总结时,看了下课表忽然意识到这已是第八周,不得不说时间过得真快,与前两年轻松的、无任务的课程相比,今年真是充实了太多!这也许是感受时间过得快的缘由,可是最近我也遇到了许多问题,当接触的知识多了之后,发现本身要学的东西太多了,仅仅上课所学远远不够,因此课后自学了一些课程,遇到的问题一是本身好高骛远,总想急于求成,这看一点那看一点,没有系统的全面的琢磨一本书,问题二:对于应用方面的知识学到手很快,但也会很快的忘记,到了应用时只记得一些概念了。对于这两个问题,我进行了一些思考,施行以下:在学习的时候把重要的知识点记录下来,我本身用的是有道云笔记,新学到的知识或者 不会的问题,经过查阅资料解决的 都把他们记录下来。效果不错,每周均可以回顾查看。最近开设了本身的博客,写博客是为了总结每日所学,反思自身。古人说“吾日三省吾身”仍是颇有道理的。在本身博客中进行知识总结,以及每周每个月思考回顾总结,感受收获良多。另外,本身也有了一些新的感悟,咱们往往感叹许多技术大牛,博客名人如何厉害,其实咱们本身就能够成为技术上的leader,其一就是知识及项目经验的不断积累,其二,我认为就是学习知识时对细节的把握,其三,能够锲而不舍,不断的学习新技术,平时不断的回顾,“温故而知新”。说了不少,实践为真,接下来还要继续本身的求知之旅。好了下面进行本周的知识总结。shell
本周进行了两天的授课,和三天的实训;主要讲解了Linux进程与线程编程中的进程之间的通讯这一方面知识。总结以下:编程
下面是我对这几种方法的理解:异步
一、无名管道(pipe ):管道是一种半双工的通讯方式,数据只能单向流动,并且只能在父子进程间通讯。管道的缓冲区是有限的(管道存在于内存中,在管道建立时,为缓冲区分配一个页面大小);管道所传送的是无格式字节流,要求管道的读出方和写入方必须事先约定好数据的格式。函数
进程A fork()出一个进程B,进程B是复制进程A的副本,获得了进程A的所有资源,所以,进程B也会有指向pd[1]的写指针,指向pd[0]的读指针。学习
因此管道这样设计:spa
进程A:线程
Close( fd [0]);设计
Write( fd[1],buffer,sizeof(buffer));指针
进程B:blog
Close(fd [1]);
Read( fd[0],buf,sizeof(buf));
二、命名管道(fifo):命名管道也是半双工的通讯方式,可是它容许无亲缘关系进程间的通讯。严格遵循先进先出(first in first out),对管道及FIFO的读老是从开始处返回数据,对它们的写则把数据添加到末尾。诸如不支持lseek()等文件定位操做。
(1)管道应用的一个重大限制是它没有名字,所以,只能用于具备亲缘关系的进程间通讯,在有名管道(named pipe或FIFO)提出后,该限制获得了克服。FIFO不一样于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。这样,即便与FIFO的建立进程不存在亲缘关系的进程,只要能够访问该路径,就可以彼此经过FIFO相互通讯(可以访问该路径的进程以及FIFO的建立进程之间),所以,经过FIFO不相关的进程也能交换数据。值得注意的是,FIFO严格遵循先进先出(first in first out),对管道及FIFO的读老是从开始处返回数据,对它们的写则把数据添加到末尾。它们不支持诸如lseek()等文件定位操做。
(2)有名管道的建立
int mkfifo(const char * pathname, mode_t mode);
该函数的第一个参数是一个普通的路径名,也就是建立后FIFO的名字。第二个参数与打开普通文件的open()函数中的mode 参数相同。 若是mkfifo的第一个参数是一个已经存在的路径名时,会返回EEXIST错误,因此通常典型的调用代码首先会检查是否返回该错误,若是确实返回该错误,那么只要调用打开FIFO的函数就能够了。通常文件的I/O函数均可以用于FIFO,如close、read、write等等。
(3)有名管道的打开规则
有名管道比管道多了一个打开操做:open。
FIFO的打开规则:
若是当前打开操做是为读而打开FIFO时,若已经有相应进程为写而打开该FIFO,则当前打开操做将成功返回;不然,可能阻塞直到有相应进程为写而打开该FIFO(当前打开操做设置了阻塞标志);或者,成功返回(当前打开操做没有设置阻塞标志)。
若是当前打开操做是为写而打开FIFO时,若是已经有相应进程为读而打开该FIFO,则当前打开操做将成功返回;不然,可能阻塞直到有相应进程为读而打开该FIFO(当前打开操做设置了阻塞标志);或者,返回ENXIO错误(当前打开操做没有设置阻塞标志)。
小结:
管道经常使用于两个方面:(1)在shell中时常会用到管道(做为输入输入的重定向),在这种应用方式下,管道的建立对于用户来讲是透明的;(2)用于具备亲缘关系的进程间通讯,用户本身建立管道,并完成读写操做。
FIFO能够说是管道的推广,克服了管道无名字的限制,使得无亲缘关系的进程一样能够采用先进先出的通讯机制进行通讯。
管道和FIFO的数据是字节流,应用程序之间必须事先肯定特定的传输"协议",采用传播具备特定意义的消息。要灵活应用管道及FIFO,理解它们的读写规则是关键。
三、消息队列(message queue ):消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。能够用非先进先出方式处理;消息队列是异步通讯的;消息队列有大小限制,一般只用于小数据量的发送;只适用于单台主机的进程间通讯;
消息队列:
提供从一个进程向另外一个进程发送一个数据块的方法
int msgget(key_t key,int msgflg);
int msgctl(int magid,int cmd,struct msgid_ds *buf);
int msgsnd(int msgid,void *msg_ptr,size_t msg_sz,int msgflag);
int msgrcv(int msgid,void *msg_ptr,size_t msg_sz,long int msg_type,int msgflag);
四、共享内存( shared memory):共享内存就是映射一段能被其余进程所访问的内存,这段共享内存由一个进程建立,但多个进程均可以访问。共享内存是最快的IPC方式。效率高,进程能够直接读写内存,而不须要任何数据的拷贝;在共享内存段中都是以字符串的默认结束符为一条信息的结尾。每一个进程在读写时都遵照这个规则,就不会破坏数据的完整性。
共享内存
容许两个不像关的进程访问同一个逻辑地址
一、int shmget(key_t key,size_t size,int shmflag);
二、void *shmat(int shm_id,const void *shm_addr,int shm_flag);
三、int shmctl(int shm_id,int cmd,struct shmid_ds *buf);
四、int shmdt(const void *shm_addr);
5.信号量(semophore ):信号量是一个计数器,能够用来控制多个进程对共享资源的访问。主要做为进程间以及同一进程内不一样线程之间的同步手段。二元信号量:与Mutex相似。
信号量:
int semget(key_t key,int num_sems,int sem_flgs);
int semctl(int sem_id,int sem_num,int command...);
int semop(int sem_id,struct sembuf *sem_ops,size_t num_sem_ops);
每一个函数的功能和参数的意义在手册中都能找到。
一、semge建立一个信号量或者获取一个已知信号量的键
key:不相关的进程能够经过他来访问同一个信号量
num_sems:须要的信号量数目。几乎老是1
sem_flags:一组标志,例如IPC_CREAT;
返回值是信号量标志符,给其余信号量函数使用
二、semctl:
sem_id:信号量标志符,semget的返回值
sem_ops:信号量编号,通常取0
command: 就不解释了,在手册中有详细的解释,我就偷偷懒吧。
三、semop
用于改变信号量的值
struct sembuf{
short sen_nums; //信号量编号,通常取0
short sem_op; //通常-1是P操做,1是V操做
short sem_flag; //一般设置为UNDO
}