文章分类 - Linux
Linux系统编程和配置
工作中常用的命令netstat、lsof、ps和top
摘要:netstat命令选项: -a all 默认不显示LISTEN相关 -t tcp -u udp -n number 不显示别名,能显示数字的都用数字显示。由于不需要把数字转换成别名,所以显示的快一些 -l listen 仅列出正在监听的服务状态 -p program 显示建立连接的程序名 -r ro
阅读全文
Linux I/O复用
摘要:epoll首先看个结构体typedef union epoll_data{ void *ptr; int fd; uint32_t u32; uint64_t u64; } epoll_data_t; struct epoll_event { uint32_t events; /* Epoll events */ epoll_data_t data; /* User data variable */ }struct epoll_event的成员events是个bit set,有几种类型:EPOLLIN:关联的文件是用来读的EPOLLOUT:关联的...
阅读全文
同步和异步、阻塞和非阻塞
摘要:首先说明我对这些概念也不是很清楚,以下内容是我做的一些理事。同步和异步、阻塞和非阻塞这是两组概念,说的是不同的事情,同步和阻塞没有必然的联系,异步和非阻塞也没有必然的联系。同步和异步是只跟IO操作过程中进程的状态变化有关。阻塞和非阻塞就是进程的两种状态。比如你去银行,排除的话就是一种同步的方式,叫号的话就是异步的方式。排队必须自己看着什么时候轮到自己,而叫号则不必,轮到你的时候会触发一个事件,或者说你会收到一个信号,别人会叫你。不管是排除还是叫号,如果你在等待的过程中不能做其他事情,那就是阻塞模式,否则就是非阻塞模式。同步的时候可以有阻塞和非阻塞,异步的时候也可以有阻塞和非阻塞。阻塞 I/OL
阅读全文
ubuntu11.10上安装网卡驱动
摘要:This is guidance for those with integrated Realtek RTL8111 series gigabit Ethernet, built in to motherboards such as the ASRock G41M-LE.Ubuntu 8.10 (and may other versions) have been reporting problems with connectivity. Here is the solution in a walk-through format. You must be root (sudo su -).1)
阅读全文
文件位置指针对read、write的影响
摘要:首先明确一下,同一个文件在同一个进程中可以被打开多次,只是返回的文件描述符不同。read、write、lseek都涉及到文件指针,文件指针是跟文件描述符关联在一起,跟物理文件是分开的。每个文件描述符都有3个指针:begin、curr、end。可以有两种方法更改curr指针:每次write或read的末位置就是curr指针的位置;使用lseek(int fd,int offset,int whence)。每次read都从curr位置开始,每次write都从begin位置开始。看一段程序: 1 #include<stdio.h> 2 #include<string.h> 3
阅读全文
子进程复制了父进程的什么
摘要:如果你对代码段、数据段、栈、堆存放哪些数据还不是很清楚,请先看我写和Linux 内存管理。有时会出现父子进程变量的地址一样,但值不一样。看下面代码:#include<stdio.h>#include<string.h>#include<stdlib.h>#include<unistd.h>main(){ char str[4]="asd"; pid_t pid=fork(); if(pid==0){ str[0]='b'; printf("子进程中str=%s\n",str); printf
阅读全文
用curses库和多线程画来回运动的字符串
摘要:使用curses库可以设置光标的位置和终端屏幕上显示的字符串样式。下面是一个使用curses库的简单示例:#include<stdio.h>#include<curses.h>void main(){ initscr(); //初始化curses库和tty clear(); //清屏 int i; for(i=0;i<LINES;i++){ move(i,i+1); //把光标移到(10,20)的位置 if(i%2==1) standout();//启动standout模式,一般使屏幕反色 adds...
阅读全文
pthread_cond_wait的思考
摘要:java中有wait()、notify()、notifyall(),Linux C中有一组函数和它们是一一对应的,实现完全相同的功能。int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);int pthread_cond_signal(pthread_cond_t * cond);int pthread_cond_broadcast(pthread_cond_t * cond);要实现java中的synchonized,在Linux C中可以使用:pthread_mutex_lock(pthread_mutex..
阅读全文
多线程基础
摘要:创建线程比创建进程快10~100倍。#include<pthread.h>int pthread_create(pthread_t *thread, pthread_attr_t *attr, //线程的属性 void *(*func)(void *), //指向线程所运行的函数的指针 void *arg); //func函数的参数void pthread_exit(void *status) 以状态status退出int pthread_join(pthread_t thread, void **retva) retv...
阅读全文
进程间协作、同步
摘要:进程和进程之间无非是通过磁盘、内核、用户空间传输数据。通过磁盘(也就是文件)实现进程通信这个好理解,服务器进程把计算结果写入文件,客户端进程从文件读数据就可以了。这里的竞争条件是当服务端正在写文件时,客户端是不允许读的。命名管道把数据写入文件,因此它可以独立于进程存在。但是命名管道是一个队列而非常规的文件,当读者把数据读走后,数据就不存在了,下一次读到的是后面的内容。普通管道位于内核,用于父子进程间通信,因此它的存在依赖于进程的存在。进程间通过文件或FIFO传输数据时,write将数据从内存复制到内核缓冲区,read将数据从内核缓冲区复制到内存。而使用共享内存是不存在用户空间和内核空间的来回复
阅读全文
fdopen和popen
摘要:popen:让进程看起来像文件#include<stdio.h>#include<stdlib.h>int main(){ FILE *fp; char buf[100]; int i=0; fp=popen("who|sort","r"); //打开一个命令,因为是只读"r",所以是要读取命令的输出 while(fgets(buf,100,fp)!=NULL) printf("%3d %s",i++,buf); pclose(fp); return 0;}$ gcc popendemo.c
阅读全文
I/O重定向和管道
摘要:I/O重定向重定向I/O的是shell而不是程序。下面的例子证明了shell并不将重定向标记和文件名传递给程序。#include<stdio.h>main(int argc,char *argv[]){ int i; printf("%d args:\n",argc); for(i=0;i<argc;i++){ printf("%s\n",argv[i]); } fprintf(stderr,"this is message sent to stderr.\n");}$ ./listargs testing >
阅读全文
环境
摘要:环境是每个程序都可以存取的一个字符串数组,每个字符串都以var=value的形式出现。在shell中列出环境:$ envORBIT_SOCKETDIR=/tmp/orbit-orisunWEKA_HOME=/home/orisun/develop/weka-3-7-4SSH_AGENT_PID=1587TERM=xtermSHELL=/bin/bashenv是一个普通的程序,它并不是shell内置命令。在shell中更新环境:$ export var=value在C语言中使用getenv()读入并修改环境:#include<stdio.h>#include<string.h&
阅读全文
execvp
摘要:问题:一个程序如何运行另一个程序?答:程序调用execvp#include<stdio.h>main(){ char *arglist[3]; arglist[0]="ls"; arglist[1]="-l"; arglist[2]=0; //参数字符串必须以0结束 printf("********About to execute ls -l\n"); execvp("ls",arglist); printf("********ls is done.bye\n");}execvp有两
阅读全文
信号通信
摘要:signalkill()不仅可以向进程发送SIGKILL信号,也可以发送其他信号。#include<signal.h>#include<sys/types.h>int kill(pid_t pid,int sig)pid的取值:正数:要发送信号的进程号0:信号被发送到所有和pid进程在同一个进程组的进程−1:信号发给所有的进程表中的进程(除了进程号最大的进程外)int raise(int sig) 进程向自身发送信号#include <unistd.h>unsigned int alarm(unsigned int seconds)alarm当定时器指定的时
阅读全文
UNIX时钟
摘要:sleep(n)和alarm(n)的精度是秒。usleep(n)挂起进程n微秒或直到有一个不能被忽略的信号到达。#include<stdio.h>#include<curses.h>void main(){ initscr(); //初始化curses库和tty clear(); //清屏 int i; for(i=0;i<LINES;i++){ move(i,i+1); //把光标移到(10,20)的位置 if(i%2==1) standout();//启动standout模式,一般使屏幕反色 a...
阅读全文
实现ll命令
摘要:$ ll wgettotal 544drwxr-xr-x 3 orisun orisun 4096 2011-12-15 09:48 ./drwxr-xr-x 65 orisun orisun 4096 2011-12-20 19:45 ../drwxr-xr-x 11 orisun orisun 4096 2011-08-09 21:55 wget-1.13/-rw-r--r-- 1 orisun orisun 540756 2011-12-15 09:47 wget.pdf目录总是不为空,它至少包含两项:.代表当前路径,..代表父路径。ll命令用于列出一个目录下的文件的详细信息:文件模式这
阅读全文
使用读写缓冲
摘要:进程缓冲区我们慢慢来说明为什么要使用缓冲:只有工作在管理员模式下,即只有内核代码才可以访问磁盘、终端、打印机等设备,还可以访问全部的内存。而用户模式下只访问特定区域的内存空间。系统调用就是要从用户空间陷入内核空间,进入管理员模式。系统调用是很花时间的,原因:(1)执行权从用户代码转移到内核代码本身要进行数据传输;(2)管理员模式对应特殊的堆栈和内存环境,系统调用前必须建立好,系统调用后又要把堆栈和内存环境恢复成用户程序运行时的状态,这种切换需要消耗很多时间。read()和write()要访问磁盘,它们是系统调用,为节约时间应尽量减少read()和write()的调用次数,为达到此目的就要增大文
阅读全文
自己编写more命令
摘要:more命令可以实现的功能是很丰富的,包括模式查找。今天我们只是实现它的一个基本功能:more 文件列表在屏幕正文显示已读的百分比按下回车显示下一行按下空格显示下一屏按下q退出按回车、空格、q时没有回显这里有几个问题:要在屏幕正文显示已读的百分比,那我们必须先获取文件列表中各个文件的长度,这个可以使用系统调用lstat#include<sys/stat.h>struct stat *buf;lstat("filename",buf) //获取文件状态filesize+=buf->st_size; //获取文件大小要显示整屏内容,我们就需要知道一屏可以显示多
阅读全文
编写who命令--从Linux中学习Linux
摘要:执行who命令查看已登录的用户信息$ whoorisun tty7 2011-12-19 14:12 (:0)orisun pts/0 2011-12-19 14:12 (:0.0)显示出了:用户名、终端名、登录时间、登录地址现在我们要自己写一个程序来实现who。是不是要用到一些特殊的系统调用,或者需要root权限呢?实际上都不用,我们要学会使用Linux的联机帮助文档,从Linux中学习Linux。要学习linux系统给我们提供的编程接口,很多时间查看相应的头文件就可以了。$ man whoWHO(1) User Commands WHO(1)NAME who - show who is l
阅读全文