
Programming int the Linux environment
文章平均质量分 89
UNIX环境高级编程、UNIX网络编程的实例总结和一些linux环境下的小项目。
主要涉及文件 I/O; 进程; 信号; 线程{线程创建, 线程控制}; 高级I/O; 进程间通信{ System V IPC, Posix IPC}; Socket
NK_test
大部分人愿意做任何事来逃避真正的思考
展开
-
基于protobuf service使用rpc入门教程
protobuf简介什么是protobufProtocol Buffers (ProtocolBuffer/ protobuf )是Google公司开发的一种数据描述语言,类似于XML能够将结构化数据序列化,可用于数据存储、通信协议等方面。现阶段支持C++、JAVA、Python等三种编程语言。在解析速度、数据描述文件大小方面都相比xml有着很大的提高,同时,我们不用再写那些吃力不讨好的协议解析类的原创 2017-05-24 21:38:33 · 35084 阅读 · 4 评论 -
Muduo 网络库源码分析 之 关键技术点总结
最近又把muduo网络库仔细研究了一遍,收获良多。本文将对muduo中的设计思想以及关键的技术细节进行总结和分析,当然由于篇幅的原因这里更多的是对关键技术的简略提及,具体细节还需要读者自己去查找学习资料。muduo/baseDate类 日期类的封装,使用Julian(儒略日)可以方便的计算日期差。具体公式和思想见 儒略日的计算Exception类 异常类的封装,对外提供what()输出错误信原创 2017-04-28 18:41:59 · 3138 阅读 · 2 评论 -
从wireshark中学网络分析(二)
在上一篇文章中提到了TCP的延迟确认,延迟确认并不一定能提高性能,在某些场景下,开启延迟确认甚至会严重降低网络传输性能。(一)下面列出几个开启延迟确认降低网络性能的场景:场景一:想象这样一个场景,服务端开启了延迟确认,客户端在同一时刻发送了9个TCP包,其中3、4、5号因为拥塞丢失了。那么传输过程中发生了以下事件: 到达服务器的6、7、8、9号包触发了4个“Ack 3”,于是客户端快速重传原创 2017-03-02 17:34:27 · 3933 阅读 · 1 评论 -
从wireshark中学网络分析(一)
网络是很抽象的,但是在wireshark里面却又是相对直观的。这里我们列举了5个问题来进一步直观地学习TCP协议,并且从中了解分析网络性能的一般方法。问题一:关于子网掩码和网关服务器A和B的网络配置如下:A:IP address: 192.168.26.129Subnet mask: 255.255.255.0Default gateway: 192.168.26.2B:IP addr原创 2017-02-26 17:34:07 · 5731 阅读 · 3 评论 -
搭建基于openvswitch vxlan协议的多主机KVM虚拟机连接环境
背景通过在物理机上启动多个KVM的方式可以用来模拟需要使用大量物理机的环境,并进行服务功能的一些验证。同一物理机上的KVM之间是可以进行通信的,但是不同物理机之间的KVM通信就需要使用openvswitch来进行连接。VXLAN(Virtual eXtensible Local Area Network)是一种将二层报文用三层协议进行封装的技术,可以对二层网络在三层范围进行扩展。VXLAN屏蔽了UD原创 2016-12-04 18:43:00 · 5837 阅读 · 0 评论 -
CPU 负载观察和性能监测
CPU负载和利用率CPU 的负载和利用率是两个不同的概念,但是他们都可以在top命令中查看。CPU利用率显示的是程序在运行期间实时占用的CPU百分比,而CPU负载显示的是一段时间内正在使用和等待使用CPU的平均任务数。CPU利用率高,并不意味着CPU的负载大。两者之间没有必然的关系。常用命令介绍:* uptime首先我们需要明白load average后面的三个数字代表什么,他们分别代表前一分钟,原创 2016-09-28 22:55:39 · 6900 阅读 · 3 评论 -
python: 知乎大规模(34k)用户爬虫
前些天学习python,完成了python练习册的大部分习题:https://github.com/Show-Me-the-Code/python(我的github上有习题代码,欢迎自取)。之后看到@salamer的一个python爬虫项目,觉得很不错。于是自己花了4天的时间完成了一个大规模爬取知乎用户信息的爬虫,由于个人网络原因,爬取12小时,获得了34k用户的信息(理论上可以爬全站的信息,可能原创 2016-05-06 14:51:25 · 23598 阅读 · 6 评论 -
Linux 下多线程排序的实现
对于计算密集型的任务,如果能采用合理的多线程处理,能够大大的提升计算效率。这篇博文实现了多线程排序,同时讲解了一些需要注意的问题。首先,说一下总体的思路:将元素分成n段,使用快速排序多个线程并行处理。最后需要等待这些线程都将分段排好序之后,进行类似归并排序的过程。这样时间复杂度算下来是(假设我是4核的机器) O(n+n/4log(n/4)),比O(nlogn)大概快了一倍的样子。(请带入数原创 2016-04-01 15:57:56 · 8481 阅读 · 0 评论 -
sed && awk工具 及一些常用的shell脚本
(一)sedsed是一个精简的、非交互式的流式编辑器,它在命令行中输入编辑命令和指定文件名,然后在屏幕上查看输出。逐行读取文件内容存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。原文件爱你的内容并没有改变。sed '4,$d' test.in # 删除4原创 2016-03-21 23:16:33 · 4997 阅读 · 1 评论 -
Shell 编程基础 --语法快速入门
简单的说shell就是一个包含若干行Shell或者Linux命令的文件。对于一次编写,多次使用的大量命令,就可以使用单独的文件保存下来,以便日后使用。通常shell脚本以.sh为后缀,第一行一定要指明系统需要哪种shell解释用户的shell程序,如:#!/bin/bash 、#!/bin/sh等。在这里我们使用#!/bin/bash。通常shell由Linux命令(外部命令)、Shell(内原创 2016-03-21 22:05:25 · 2912 阅读 · 1 评论 -
Linux下简单线程池的实现
线程池的技术背景 在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁。如何利用已有对象来服务(不止一个不同的任务)就是一个需要解决的关键问题,其实这就是一些"池原创 2016-03-09 15:23:19 · 5025 阅读 · 2 评论 -
gdb常用调试命令以及多线程堆栈的查看
GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。或许,各位比较喜欢那种图形界面方式的,像VC、BCB等IDE的调试,但如果你是在UNIX平台下做软件,你会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的功能。所谓“寸有所长,尺有所短”就是这个道理。一般来说GDB主要调试的是C/C++的程序。要调试C/C++的程序,首先在编译时,我们必须要把调试信息加到可执行文件中。原创 2016-03-03 23:32:53 · 32219 阅读 · 3 评论 -
面向对象编程风格 & 基于对象编程(boost::bind/function)
“Muduo是一个现代的 C++ 网络库。现代和古代的API区别在于两方面。一个是事件回调,另外一个是资源管理。一般的网络库设计API的方式是定义一个接口(抽象基类),包含几种网络事件对应的处理函数。你的代码去继承这个接口,这个接口会定义收到消息是回调哪个虚函数,然后你覆盖一下这个虚函数。然后把你的对象注册到网络库中,发生事件的时候就回调你的虚函数。一般的 Framework 都这么搞,这就是原创 2016-02-15 21:47:11 · 3642 阅读 · 1 评论 -
浅谈网络I/O多路复用模型 select & poll & epoll
我们首先需要知道select,poll,epoll都是IO多路复用的机制。I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的。select的基本用法:http://blog.csdn.原创 2016-02-14 16:24:06 · 4462 阅读 · 0 评论 -
大并发服务器架构 && 大型网站架构演变
服务器的三条要求:高性能:对于大量请求,及时快速的响应高可用:7*24 不间断,出现故障自动转移,这叫fail over(故障转移)伸缩性:使用跨机器的通信(TCP)另外任何网络系统结构都可以抽象成C/S架构,我们常说的B/S模式本质上也是C/S架构(浏览器看作客户端)。一个典型的服务器架构:注: epoll是linux下最高效的网络I/O由于服务器需要高效处理原创 2016-01-30 13:59:54 · 4567 阅读 · 0 评论 -
Linux下FTP服务器的实现(仿vsftpd)
继上一篇博文实现Linux下的shell后,我们进一步利用网络编程和系统编程的知识实现Linux下的FTP服务器。我们以vsftpd为原型并实现了其大部分的功能。由于篇幅和时间的关系,这里不再一一赘述具体的实现过程,而是简要概述功能实现思想和部分核心代码。(一)基本框架和流程先解决两个疑问:(1)为什么要使用nobody进程和服务进程两个进程? 在PORT模原创 2016-01-24 22:09:15 · 11545 阅读 · 13 评论 -
哈希表之开地址法解决冲突
在上一篇博文中,我们讲述了使用链地址法解决冲突的方法。这里我们介绍另一种方式:开地址法解决冲突。基本思想:当关键码key的哈希地址H0 = hash(key)出现冲突时,以H0为基础,产生另一个哈希地址H1 ,如果H1仍然冲突,再以H0为基础,产生另一个哈希地址H2 ,…,直到找出一个不冲突的哈希地址Hi ,将相应元素存入其中。根据增量序列的取值方式不同,相应的再散列方式也不同原创 2016-01-23 13:20:41 · 4199 阅读 · 0 评论 -
哈希查找之链地址法解决冲突(代码封装实现)
链地址法的基本思想是:将所有哈希地址为i 的元素构成一个称为同义词链的链表,并将链表的头指针存在哈希表的第i个单元中,因而查找、插入和删除主要在同义词链中进行。 该散列方法首先对关键码集合用某一个散列函数计算它们的存放位置。若设散列表地址空间的所有位置是从0到m-1,则关键码集合中的所有关键码被划分为m个子集,具有相同地址的关键码归于同一子集。我们称同一子集中的关键码互为同义词原创 2016-01-15 22:28:13 · 6418 阅读 · 1 评论 -
Linux多线程实践(六)使用Posix条件变量解决生产者消费者问题
前面的一片文章我们已经讲过使用信号量解决生产者消费者问题,那么什么情况下我们需要引入条件变量呢?这里借用 http://www.cnblogs.com/ngnetboy/p/3521547.html 的解释:假设有共享的资源sum,与之相关联的mutex 是lock_s.假设每个线程对sum的操作很简单的,与sum的状态无关,比如只是sum++.那么只用mutex足够了.程序员只要确原创 2016-01-15 18:03:22 · 3793 阅读 · 0 评论 -
Linux下具有基本功能的shell的具体代码实现(详细)
在前几个月对Linux的学习过程中,一直在与shell进行交互,感觉shell充满了神秘感。偶然看到一篇文章讲解了shell的实现,感觉也不是很难的样子,于是自己也开始开发自己的minishell,顺便也巩固了前一段时间学习的linux系统编程的知识。先来展示一下我的这个minishell实现的功能:1. 支持ls,touch,wc 等外部命令2. 支持输入输出重定向符3.原创 2015-11-15 22:24:32 · 13889 阅读 · 2 评论 -
Linux多线程实践(五 )Posix信号量和互斥锁解决生产者消费者问题
一点区别:system v 信号量只能用于进程间同步,而posix 信号量除了可以进程间同步,还可以线程间同步。system v 信号量每次PV操作可以是N,但Posix 信号量每次PV只能是1。除此之外,posix 信号量还有命名和匿名之分(man 7 sem_overview):Posix 信号量有名信号量无名信号量原创 2016-01-03 19:24:35 · 5423 阅读 · 0 评论 -
Linux多线程实践(四 )线程的特定数据
在单线程程序中,我们经常要用到"全局变量"以实现多个函数间共享数据, 然而在多线程环境下,由于数据空间是共享的,因此全局变量也为所有线程所共有。但有时应用程序设计中有必要提供线程私有的全局变量,仅在某个线程中有效,但却可以跨多个函数访问。POSIX线程库通过维护一定的数据结构来解决这个问题,这个些数据称为(Thread-specific-data或 TSD)。相关函数如下:int pthr原创 2016-01-02 21:30:56 · 13323 阅读 · 2 评论 -
Linux多线程实践(三)线程的基本属性设置API
POSIX 线程库定义了线程属性对象 pthread_attr_t ,它封装了线程的创建者可以访问和修改的线程属性。主要包括如下属性:1. 作用域(scope)2. 栈尺寸(stack size)3. 栈地址(stack address)4. 优先级(priority)5. 分离的状态(detached state)6. 调度策略和参数(sc原创 2016-01-01 18:14:59 · 3335 阅读 · 0 评论 -
Linux多线程实践(二)线程基本API(POSIX)
我们知道,进程在各自独立的地址空间中运行,进程之间共享数据需要用进程间通信机制,有些情况需要在一个进程中同时执行多个控制流程,这时候线程就派上了用场,比如实现一个图形界面的下载软件,一方面需要和用户交互,等待和处理用户的鼠标键盘事件,另一方面又需要同时下载多个文件,等待和处理从多个网络主机发来的数据,这些任务都需要一个“等待-处理”的循环,可以用多线程实现,一个线程专门负责与用户交互,另外几个线程原创 2015-12-28 22:54:51 · 4072 阅读 · 1 评论 -
Linux多线程实践(一)线程基本概念和理论
线程概念 在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是“一个进程内部的控制序列/指令序列”; 对于每个进程至少有一个执行线程;进程 VS. 线程 1.进程是资源分配(进程需要参与资源的竞争)的基本单位,而线程是处理器调度(程序执行)的最小单位; 2.线程共享进程数据,但也拥有自己的一部分数据,如原创 2015-12-16 12:44:07 · 4053 阅读 · 1 评论 -
Linux进程间通信(IPC)编程实践(十二)Posix消息队列--基本API的使用
posix消息队列与system v消息队列的差别:(1)对posix消息队列的读总是返回最高优先级的最早消息,对system v消息队列的读则可以返回任意指定优先级的消息。(2)当往一个空队列放置一个消息时,posix消息队列允许产生一个信号或启动一个线程,system v消息队列则不提供类似机制。队列中的每个消息具有如下属性:1、一个无符号整数优先级(pos原创 2015-12-13 21:31:35 · 395016 阅读 · 1 评论 -
Linux进程间通信(IPC)编程实践(十一)System V信号量---实现一个先进先出的共享内存shmfifo
使用消息队列即可实现消息的先进先出(FIFO), 但是使用共享内存实现消息的先进先出则更加快速; 我们首先完成C语言版本的shmfifo(基于过程调用), 然后在此基础上实现C++版本的ShmFifo, 将1块共享内存与3个信号量(1个mutext信号量, 1个full信号量, 1个empty信号量)封装成一个类ShmFifo, 然后编写各自的测试代码; shmfifo原创 2015-12-08 14:25:39 · 2920 阅读 · 0 评论 -
Linux进程间通信(IPC)编程实践(十)System V信号量---PV操作经典题目
[cpp] view plaincopy//P原语 //P(semaphore *S) wait(semaphore *S) { -- S->value; if (S->value { //将当前进程设置为阻塞状态原创 2015-12-06 20:44:00 · 3621 阅读 · 0 评论 -
Linux进程间通信(IPC)编程实践(九)System V信号量---封装一个信号量操作的工具集
System信号量集主要API[cpp] view plaincopy#include #include #include int semget(key_t key, int nsems, int semflg); int semctl(int semid, int semnum, int cmd, ...); i原创 2015-12-03 22:49:00 · 2734 阅读 · 0 评论 -
Linux进程间通信(IPC)编程实践(六)共享内存的使用-mmap
共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据(如图)。共享内存和其他进程间通信方式的比较:用管道或者消息队列传递数据:使用共享内存传递数据:共享内存生成之后,传递数据并不需要再走Linux内核,共享内存允许两个或多个进程共享一个给定原创 2015-11-21 14:46:21 · 3340 阅读 · 0 评论 -
Linux进程间通信(IPC)编程实践(七)共享内存的使用-System V共享内存(API)
上一篇博文提到的系统调用mmap通过映射一个普通文件实现共享内存。那么本文中介绍的System V 共享内存则是通过映射特殊文件系统shm中的文件实现进程间的共享内存通信。也就是说,每个共享内存区域对应特殊文件系统shm中的一个文件。执行过程是先调用shmget,再调用shmat。对于每个共享的内存区,内核维护如下的信息结构,定义在头文件中。//System V 共享内存基本数据结构原创 2015-11-22 22:05:19 · 1867 阅读 · 0 评论 -
Linux进程间通信(IPC)编程实践(五)消息队列实现回射客户/服务器
在我的上一篇博文中,讲解了关于消息队列的msgsnd和msgrcv函数的使用,这里我们试着来实现一个回射客户/服务器。基本框架如下:对于客户端: 用进程的PID进行区分类型,发往服务器的类型(mtype)总是1,包含自己的PID,还有一行消息。对于回射服务器端: 创建一个消息队列,指定键值是1234,服务器不停地接受类型是1的消息,解析出数据部分的pid(mtext的前四个原创 2015-11-16 15:55:24 · 2436 阅读 · 0 评论 -
Linux进程间通信(IPC)编程实践(八)共享内存的使用-POSIX 共享内存(API)
1、Posix提供了两种在无亲缘关系进程间共享内存区的方法:(1)内存映射文件:先有open函数打开,然后调用mmap函数把得到的描述符映射到当前进程地址空间中的一个文件(上一篇博文所用到的就是)。(2)共享内存区对象:先有shm_open打开一个Posix IPC名字(也可以是文件系统中的一个路径名),然后调用mmap将返回的描述符映射到当前进程的地址空间。这两种方法都需要调用m原创 2015-11-23 22:03:54 · 3307 阅读 · 0 评论 -
Linux进程间通信(IPC)编程实践(三) 详解System V消息队列(1)
消息队列简介消息队列提供了一个从一个进程向另外一个进程发送一块数据的方法(本机);每个数据块都被认为是有一个类型,接收者进程接收的数据块可以有不同的类型值。消息队列也有管道一样的不足: (1)每个消息的最长字节数的上限(MSGMAX); (2)系统中消息队列的总条数也有一个上限(MSGMNI); (3)每个消息队列所能够保存的总字节数是有上限的(MSGMNB) .原创 2015-11-10 13:04:16 · 2615 阅读 · 0 评论 -
Linux进程间通信(IPC)编程实践(0) 进程间通信简述和PV原语
进程的同步与互斥 进程同步: 多个进程需要相互配合共同完成一项任务。 进程互斥: 由于各进程要求共享资源,而且有些资源需要互斥使用,因此各进程间竞争使用这些资源,进程的这种关系为进程的互斥;系统中某些资源一次只允许一个进程使用,称这样的资源为临界资源或互斥资源, 而在进程中涉及到互斥资源的程序段叫临界区.对于多个进程的并发状态,进程是基于CPU时间片轮转的。原创 2015-10-28 23:18:59 · 2037 阅读 · 0 评论 -
Linux下的socket编程实践(十) 基本UDP编程细节
在我的这两篇博客中,简单介绍并实现了基于UDP(TCP)的windows(UNIX下流程基本一致)下的服务端和客户端的程序,本文继续探讨关于UDP编程的一些细节。http://blog.youkuaiyun.com/nk_test/article/details/47733307http://blog.youkuaiyun.com/nk_test/article/details/47756381下图是一个原创 2015-10-26 23:54:02 · 3201 阅读 · 0 评论 -
Linux下的socket编程实践(九) epoll实现高并发的原理及其使用
在 linux 没有实现 epoll 事件驱动机制之前,我们一般选择用 selec t或者 poll 等IO多路复用的方法来实现并发服务程序(详见此链接)。在大数据、高并发、集群等一些名词唱得火热之年代,select 和 poll的用武之地越来越有限,风头已经被 epoll 占尽。 本文便来介绍 epoll 的实现机制,并通过对比其不同的实现机制,真正理解为何 epoll 能实现高并发原创 2015-10-22 12:03:19 · 9431 阅读 · 1 评论 -
Linux下的socket编程实践(八) Select的限制和poll(并发的初步知识)
select的限制用select实现的并发服务器,能达到的并发数一般受两方面限制:1)一个进程能打开的最大文件描述符限制。这可以通过调整内核参数来改变。可以通过ulimit -n(number)来调整或者使用setrlimit函数设置(需要root权限),但一个系统所能打开的最大数也是有限的,跟内存大小有关,可以通过cat /proc/sys/fs/file-max 查看。原创 2015-10-20 22:44:42 · 5151 阅读 · 1 评论 -
Linux下的socket编程实践(七) I/O多路复用技术之select模型
在进入今天的select模型的主题之前,我们先来简单了解一下五种I/O模型:(1)阻塞I/O(默认采用这种方式)在服务端socket编程中,我们常见的accpet函数、recv函数都是采取的阻塞形式。以recv为例: 当上层应用App调用recv系统调用时,如果对等方没有发送数据(Linux内核缓冲区中没有数据),上层应用Application1将阻塞;当对等方发送了数据,Linu原创 2015-10-19 22:58:57 · 5192 阅读 · 0 评论 -
Linux下的socket编程实践(六)Unix域协议和socketpair传递文件描述符
UNIX域协议并不是一个实际的协议族,而是在单个主机上执行客户/服务器通信的一种方法,所用API与在不同主机上执行客户/服务器通信所使用的API相同。UNIX域协议可以视为IPC方法之一,Unix域协议主要用在同一台机子(仅能用于本地进程间的通信)的不同进程之间传递套接字。为什么不用TCP或者UDP套接字呢?1)在同一台主机上, UNIX域套接字更有效率, 几乎是TCP的两倍(由于UNIX域套原创 2015-10-13 23:42:49 · 4557 阅读 · 2 评论