/*********************************************/
进程控制
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int statloc);
pid_t waitpid(pid_t pid, int statloc,int options);
区别:在一个子进程终止前,wait使其调用都阻塞,而waitpid有一选择项,可使调用都不阻塞
waitpid,等待指定进程终止
参数pid == -1 等待任一子进程
pid > 0 等待基ID与pid相等的子进程
pid == 0等待其组ID等待调用进程的组ID的任一子进程
pid < -1 等待其组ID等待pid的绝对值的任一子进程
options
WNOHANG 若由p i d指定的子进程并不立即可用,则w a i t p i d不阻塞,此时其返回值为0
WUNTRACED 若若某实现支持作业控制,则由p i d指定的任一子进程状态已暂停,且其状态自暂
停以来还未报告过,则返回其状态。
exec函数
exec只是用另一个新程序替换了当前进程的正文、数据、堆和栈段
#include <unistd.h>
int execl(const charp a t* h n a m e, const char a* rg 0, ... /* (char *) 0 */);
int execv(const charp a t* h n a m e, char *consta rgv [] );
int execle(const charp a t* h n a m e, const char a* rg 0, ...
/* (char *)0, char *cones nt v p [] */);
int execve(const charp a t* h n a m e, char *consta rgv [], char *consten vp [] );
int execlp(const charf i l e* n a m e, const char a* rg 0, ... /* (char *) 0 */);
int execvp(const charf i l e* n a m e, char *consta rgv [] );
unsigned int alarm(unsigned int seconds)
建立一个进程的报警时钟,在时钟定时器到时的时候,用信号向程序报告。
参数seconds,其以秒为单位给出了定时器的时间,当时间到达的时候,就向系统发送一个SIGARLM信号
pause(void)
能使调用进程暂停执行,直至接收到某种信号为止.
/**********************************************/
System V IPC
IPC对象在程序中是通过关键字(key)来访问,要访问同一个IPC对象,sever和client必须使用同一个关键字
生成关键字函数 ftok()
key_t ftok(char *pathname,char proj);
消息队列(先入先出)
消息队列就是在系统内核中保存的一个用来保存消息的队列
基本数据结构
用来保存IPC对象权限信息.
#include <linux/ipc.h>
struct ipc_perm
{
key_t key;
ushort uid;
ushort gid;
ushort cuid;
ushort cgid;
ushort mode;
ushort seq;
};
自定义传递给队列的消息的数据类型
#include <linux/msg.h>
struct msgbuf{
long mtype; //区分不同消息数据类型,最大长度<=4056
char mterxt[1]; //消息数据内容
};
消息队列在系统内核以消息链表的形式出现,而完成消息链表每个节点结构定义的就是msg结构
struct msg{
struct msg *msg_next; //指向消息链表中下一个节点的指针
long msg_type; //消息类型
char *msg_spot; //指出了消息内容在内存中的位置
time_t msg_stime;
short msg_ts; //消息内容的长度
};
被系统内核用来保存消息队列对象有关数据
struct msqid_ds{
struct ipc_perm msg_perm; //存取权限
struct msg *msg_first; /* 第一个成员的地址 */
struct msg *msg_last; /* 最后一个成员的地址 */
__kernel_time_t msg_stime; /* 最近一次队列接受消息的时候 */
__kernel_time_t msg_rtime; /* 最近一次从队列中取出消息的时间 */
__kernel_time_t msg_ctime; /* 最近一次队列发生改动的时间 */
struct wait_queue *wwait; //指向系统内部等待队列的指针
struct wait_queue *rwait;
unsigned short msg_cbytes; /* 保存队列总共占用内存的字节数 */
unsigned short msg_qnum; /* 保存队列里保存的消息数目 */
unsigned short msg_qbytes; /* 保存队列所占内存最大字节数 */
__kernel_ipc_pid_t msg_lspid; /* 最近一次向队列发送消息的进程的pid */
__kernel_ipc_pid_t msg_lrpid; /* 最近一次向队列中取出消息的进程pid */
};
处消息队列基本函数
1.msgget()用创建新的消息队列或获取已有的消息队列
int msgget(key_t key,int msgflg)
参数key,消息队列对象的关键字
msgflg,操作控制:
IPC_CREAT 对象不存在,创建,否则打开操作
IPC_EXCL 和IPC——CREAT如消息对象不存在则创建,否则产生一个错误
2.msgsnd用来向消息队列发送消息
int msgsnd(int msqid,struct msgbuf *msgp,int msgsz,int msgflg)
参数:
msqid,消息队列对象标识符
msgp,指向要发送的消息所在的内存
msgsz,要发送信息的长度(字节数)
msgflg,控制函数行为标志 ,0表示忽略标志位,IPC_NOWAIT如消息队列已满,消息将不被写入队列
3.msgrcv用来消息队列取出消息
int msgrcv(int msqid,struct msgbuf *msgq,int msgsz,long mtype,int msgflg);
参数:
msqid,消息队列对象标识符
msgp,指向要发送的消息所在的内存
msgsz,要发送信息的长度(字节数)
mtype,所取的消息类型
msgflg,控制函数行为标志 ,0表示忽略标志位,IPC_NOWAIT如消息队列已满,消息将不被写入队列
4.msgctl函数控制消息队列的行为
int msgctl(int msgqid,int cmd,struct msgqid_ds *buf)
参数:
msgqid,消息队列对象标识符
cmd,可以是:
IPC_STAT取出系统保存的消息队列msqid_ds数据,并将其存入参数buf指向的msqid_ds结构中
IPC_SET设定消息队列的msqid_ds结构中msg_perm成员
IPC_EMID将列队从系统内核删除
信号量
简单说用来控制多个进程对共享资源使用的计数器,是一种锁定保护机制,当某个进程在对资源进行操作时阻止其它进程对
该资源的访问
基本数据结构
1.信号量对象实际是多个信号量的集合
struct sem{
short sempid; //保存最近一次操作信号量的进程pid
ushort semval; //保存信号量的计数值
ushort semncnt; //保存等待使用资源的进程数目
ushort semzcnt; //保存等待资源完空闲的进程数目
};
2.semun联合在senctl()函数中使用,提供senctl操作所需要的信息
union semun{
int val;
struct semid_ds *buf;
ushort *array;
struct seminfo *__buf;
void *__pad;
};
3.sembuf结构被semop()函数用来定义对信号量对象的基本操作
struct sembuf{
unsigned short sem_num; //为接受操作的信号量在信号量数组中的序号(数组下标)
short sem_op; //定义了进行的操作(可以是正、负、0)
short sem_flg; //控制操作行为的标志
};
参数sem_op:
1)负值,就从指定的信号量中减去相应的值,这对应着获取信号量所监控的源资的操作
2)正值,就在指定的信号量中加上相应的值,这对应着释放信号量所监控的资源的操作
3)0,那么调用semop()函数的进程就会被阻塞直到对应的信号量值为0,这种操作的实质就是等待信号量所监控的资源被全部
使用
4.semid_qs结构被系统用来储存每个信号量对象有关信息
struct semid_ds {
struct ipc_perm sem_perm; /* 信号量的存取权限 */
__kernel_time_t sem_otime; /* 保存一次semop()操作时间 */
__kernel_time_t sem_ctime; /* 保存了信号量对象最近一次改动发生的时间 */
struct sem *sem_base; /* 保存信号量数组的起始地址 */
struct sem_queue *sem_pending; /* 保存着还没有进行的操作 */
struct sem_queue **sem_pending_last; /* 保存最后一个还没有进行的操作 */
struct sem_undo *undo; /* 保存了undo请求的数目 */
unsigned short sem_nsems; /* 保存了信号量数组的成员数目 */
};
基本函数
1.semget函数用来建立新的信号量对象或者获取已有对象的标识符
#include <linux/sem.h>
int semget(key_t key,int nsems,int semflg)
参数:
key,关键字
nsems,指信号量数组成员个数
semflg,操作控制:
IPC_CREAT 对象不存在,创建,否则打开操作
IPC_EXCL 和IPC——CREAT如消息对象不存在则创建,否则产生一个错误
2.semop函数来改变信号量中各个信号量的状态
int semop(int semid,struct sembuf *spos,unsigned nsops);
参数:
semid,信号量对象的标识符
sops,是sembuf的数组,定义所要进行的操作序列
nsops,保存sops数组的长度,也即semop()函数进行的操作个数
例:打印交付一份作业
struct sembuf sem_get = {0,-1,IPC_NOWAIT}; //获取资源
if(semop(sid,&sem_get,1) == -1) //使用
perror("semop");
struct sembuf sem_release = {0,1,IPC_NOWAIT}; //释放资源
semop(sid,&sem_release,1);
3.semctl函数用来直接对信号量对象进行控制
int semctl(int semid,int semnum,int cmd,union semun arg);
参数:
semid,信号量对象标识符
semnum,信号数目
cmd,有:
IPC_STAT取得信号量对象的semid_ds 结构信息,并将其储存在arg参数中buf指针所指内存中返回
IPC_SET用arg参数中buf的数据来设定信号量的semid_ds结构信息
IPC_RMID从内存中删除信号量对象
GETALL取得信号量对象中所有信号量的值,并储存在arg参数中的array数组中返回
GETNCNT返回正在等待使用某个信号量所控制的资源的进程数目
GETPID返回最近一个对某个信号量调用semop函数的进程的pid
GETVAL返回对象中某个信号量的数值
GETZCNT返回正在等待某个信号量所控制资源被被全部使用的进程数目
SETALL用arg参数中array数组的值来设定对象内各个信号量的值
SETVAL用arg参数中val成员的值来设定对象内某个信号量的值
arg,提供了操作所需要的其它信息
共享内存
简单说就是被多个进程共享的内存,是将信息直接映射到内存中,所通信方法中最快
基本数据结构
shmid_ds给系统内存用来保存相关信息
struct shmid_ds{
struct ipc_perm shm_perm; /* 共享内存对象存取权限及其它一些信息 */
int shm_segsz; /* 共享内存大小 */
__kernel_time_t shm_atime; /* 最近一次进程连接共享内存的时间 */
__kernel_time_t shm_dtime; /* 最近一次进程断开与共享内存的连接的时间*/
__kernel_time_t shm_ctime; /* 保存了最近一次shmid_ds 结构内容改变的时间 */
__kernel_ipc_pid_t shm_cpid; /* 创建共享内存的进程的pid */
__kernel_ipc_pid_t shm_lpid; /* 保存了最近一次连接共享内存的进程的pid */
unsigned short shm_nattch; /* 保存了与共享内存连接的进程数 */
unsigned short shm_unused;
void *shm_unused2;
void *shm_unused3;
};
基本函数
1.shmget函数创建新的或取得已有的共享内存
int shmget(key_t key,int size,int shmflg)
参数:
key,共享内存的关键字
size,创建的共享内存大小
shmflg,控制函数行为的标志量
2.shmat()当一个进程使用shmget函数得到共享内存标识符后,再使用shmat将共享内存映射到进程自己的内存空间内
int shmat(int shmid,char *shmaddr,int shmflg)
参数:
shmid,共享内存标识符
shmaddr,指定了共享内存映射地址,0为自动为映射分配一块未使用的内存
shmflg,指定了地址后,用SHM_RND标志来强迫将内存大小设定为页面的尺寸,SHM_RDONLY共享内存将被映射成只读
返回值,返回指向映射内存的指针
3.shmctl控制操作函数
int shmctl(int shmqid,int cmd,struct shmid_ds *buf);
参数:
cmd有:IPC_STAT获取共享内存的信息
IPC_SET设定共享内存的信息
IPC_RMID删除共享内存
说明:当执行IPC_RMID 操作时,系统并不是立即将其删除,而只是将其标
为待删,然后等待与其连接的进程断开连接。只有当所有的连接都断开以后系统才执行真
正的删除操作。当然,如果执行IPC_RMID 的时候没有任何的连接,删除将是立即的。
4.shmdt当一进程不再需要某个共享内存的映射时,使用该函数断开映射,释放资源
int shmdt(char *shmaddr)
参数:
shmaddr,为共享内存映射的地址
/**********************************************************/
20110324
#include <getopt.h>
int getopt_long(int argc,char *const argv[],const char *optstring,const struct option *longopts,int
*longindex);
参数:
argc,参数个数
argv[],具体参数数组
optstring,字符串缩写
longopts,指各option结构的数组,被称为长选项表
longindex,如没有变量设置NULL,那么它指各一个变量,这个变量会被赋值为寻找到的长选项在longopts中的索引值,可以
用于错误诊断
option结构:
struct option{
const char *name; //选项名
int has_arg; //描述选项是否有选项参数
int *flag; //
int val; //长选项时的返回值
};
stat()功能得到文件的信息
#include <sys/stat.h>
int stat(const char *path,struct stat *buffer);
参数:
path,文件路径名
buffer,struct stat结构
struct stat {
mode_t st_mode; //文件对应的模式,文件,目录等
ino_t st_ino; //i-node节点号
dev_t st_dev; //设备号码
dev_t st_rdev; //特殊设备号码
nlink_t st_nlink; //文件的连接数
uid_t st_uid; //文件所有者
gid_t st_gid; //文件所有者对应的组
off_t st_size; //普通文件,对应的文件字节数
time_t st_atime; //文件最后被访问的时间
time_t st_mtime; //文件内容最后被修改的时间
time_t st_ctime; //文件状态(属性)改变时间
blksize_t st_blksize; //文件内容对应的块大小
blkcnt_t st_blocks; //文件内容对应的块数量
};
/***************************************/
web服务器编程分析
1.分析用户输入命令行,获取ip,port,监听数,网页根目录
2.创建守护进程
3.创建服务器socket端,新建socket,绑定用户输入的IP,PORT,监听连听,不断循环接受新的浏览器客户端访问
4.fork子进程来处理客户端请求,父进程继续等待
5.客户端成功链接后,获取客户端请求的HTTP头信息
6.解析HTTP请求的信息,回应每个请求,写出客户端socket描述符,具体:
1.获取客户端实际访问工作目录
2.获取客户端每次访问端口
3.获取实际工作目录或文件的信息,判断是文件还是目录
4.回应客户端,返回具体页面,代码:
HTTP/1.1 200 OK
Server: DAS by ZhouLifa
Connection: close
<html><head><title>0 - NULL</title></head>"
"<body><font size=+4>Linux 下目录访问服务器</font><br><hr width=/"100%%/"><br><center>"
"<table border cols=3 width=/"100%%/">"
5.处理文件访问,显示.只读方式打开文件,获取文件大小,保存文件数据,写回浏览器客户端;下载文件代码:
HTTP/1.1 200 OK
Server: DAS by ZhouLifa
Connection: keep-alive
Content-type: application/*
Content-Length:1024+1
6.处理浏览目录请求,显示目录名称大小,修改时间,显示目录下面所有文件或目录
/**************************************************/