进程控制

/*********************************************/

 

进程控制

 

#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.处理浏览目录请求,显示目录名称大小,修改时间,显示目录下面所有文件或目录

 

 

 

/**************************************************/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值