Chinaunix首页 | 论坛 | 博客

Neo

  • 博客访问: 38936
  • 博文数量: 7
  • 博客积分: 372
  • 博客等级: 二等列兵
  • 技术积分: 85
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-24 21:46
文章分类
文章存档

2012年(7)

分类: 系统运维

2012-04-18 19:41:30

/*
 * 这是一个UNIX & LINUX 下开发使用的常量信息整理文档。
 * 可以查找常量使用于取值信息。
 * */
 

 


环境变量
name=value
#include  <stdio.h>
char *getenv(const char * name)
返回:指向name的value的指针,若为找到返回NULL

POSIX.1 和XPG3的基础环境变量
-------------------------------------------------------
环境变量       标准               实现         说明
           ---------------------------------
            POSIX.1  XPG3     SVR4  4.3+BSD 
-------------------------------------------------------
HOME           *       *       *         *     起始目录
LANG           *       *       *               本地名
LC_ALL         *       *       *               本地名 
LC_COLLATE     *       *       *               本地排序名
LC_CTYPE       *       *       *               本地字符分类名
LC_MONETARY    *       *       *               本地货币编辑名
LC_NUMERIC     *       *       *               本地数字编辑名
LC_TIME        *       *       *               本地日期/时间格式名
LOGNAME        *       *       *         *     登录名
NLSPATH                *       *               消息类模板序列
PATH           *       *       *         *     搜索可执行文件的路径前缀表
TERM           *       *       *         *     终端类型
TZ             *       *       *         *     时区信息

------------------------------------------------------- 

对各种环境表函数的支持

------------------------------------------------------- 
函数         标准                     实现      
          ---------------------------------------------
          ANSI C   POSIX.1  XPG3      SVR4  4.3+BSD 
-------------------------------------------------------   
getenv      *         *       *         *      *
putenv               可能     *         *      *            
setenv                                         * 
unsetenv                                       * 
clearenv             可能
-------------------------------------------------------    
#include <stdlib.h>
int putenv(const char *str);
int setenv(const char *name,const char *value,int rewrite);
返回:若成功返回0 ,失败为非0
void unsetenv(const char *name); //删除指定的环境变量。


setjmp longjmp 函数
不允许使用goto语句。进行跳转功能,可以通过setjmp和longjmp.    
#include <setjmp.h> 
int setjmp(jmp_buf env);
void longjmp(jmp_buf env,int val);
返回:直接调用返回0 若从logjmp返回非0
自动、寄存器和易失变量
如果longjmp 返回调用函数后不不希望变量值进行回滚着使用volatile进行定义。
sigsetjmp 和siglongjmp 信号跳转控制。

getrlimit和setrlimit函数
每个进程都有一组资源限制通过getrlimit和setrlimit函数查询和更改。
#include <sys/time.h>
#include <sys/resource.h>
int getrlimit(int resource,struct relimitr lptr);
int setrlimit(int resource,const  struct relimitr lptr);
返回:成功为0 ,失败为非0

struct rlimit{
    rlim_t rlim_cur;//soft limit : current limit 
    rlim_t rlim_max;//hard limit : maximum value for rlim_cur
    }
资源限制原则
1 任何一个进程都可将一个软限制更改为小于或等于其应限制。
2 任何一个进程都可降低其硬制值,但它必须大于或等于其软件限制值。这种降低,对普通用户而言是不可逆反的。
3 只有超级用户可以提高硬限制。
无限量的限制由常数RLIM_IMFINITY指定。
resource 的取值
RLIMIT_CORE    core 文件的最大字节数,若其值为0则阻止创建core文件。
RLIMIT_CPU     CPU时间的最大量值(秒),当超过此软件限制时,向该进程发送SIGXCPU信号。
RLIMIT_DATE    数据段的最大字节长度。
RLIMIT_ESIZE   可以创建的文件最大字节长度。超过此软限制时,则向该进程发送SIGXFSZ信号。
RLIMIT_MEMLOCK 锁定在存储器地址空间(尚未实现)
RLIMIT_NOFILE  每个进程能打开的最多文件数,更改此限制将影响到sysconf函数在参数_SC_OPEN_MAX中的返回值。
RLIMIT_NPORC   每个实际用户ID所拥有的最大子进程数。更改此限制将影响到sysconf函数在参数_SC_CHILD_MAX返回值。
RLIMIT_RSS     最大驻内存集字节长度(RSS).
RLIMIT_STACK   栈的最大字节长度。
RLIMIT_VMEM    可映照地址空间的驻地啊字节长度。影响到mmap函数。
资源限制可以被子进程继承。

8 章 进程控制
@进程标识
#include <sys/types.h>
#include <unistd.h>
pid_t getpid(void); //返回:调用进程的进程ID
pid_t getppid(void);//返回:调用进程的父进程ID 
uid_t getuid(void); //返回:调用进程的实际用户ID
uid_t geteuid(void);//返回:调用进程有效用户ID
gid_t getgid(void); //返回:调用进程的实际组ID
gid_t getegid(void);//返回: 调用进程的有效组ID
@ fork函数
创建一个继承
#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);//返回:子进程中为0 ,父进程中子进程ID,出错返回-1. 
                            
#include <sys/types.h>  
#include <sys/wait.h>
pid_t wait(int *stalioc);
pid_t waitpid(pid_t pid,int *statloc,int optinos);
//返回:成功返回ID 错误返回-1

                           
#include <sys/wait.h>
int waitid(idtype_t idtype,id_t id,siginfo_t *infop,int options);
/*
idtype:
P_PID   等待一个特定的进程,id要等待的进程ID
P_PGID  等待一个特定的进程组中的任何一个子进程,id包含要等待的子进程的进程组ID
P_ALL   等待任一子进程,忽略id
options:
WCONTINUED  等待一个进程,它以前曾被暂停,此后又被继续,但其状态尚未报告
WEXITED     等待已退出的进程
WNOHANG     如无可用的子进程退出状态,立即返回而非阻塞。
WNOWAIT     不被坏子进程退出状态,该子进程退出状态可由后续的wait,waitid 或waitpid调用取得
WSTOPPED    等待一个进程,他已经暂停,但其状态尚未报告。
*/


#include <unistd.h>
int execl(const char *pathname, const char *arg0,... /* (char *))*/);
int execv(const char *pathname, char *const argv[]);
int execle(const char *pathname, const char *arg0, ... ,/* (char *)0 ,char *const envp[]*/);
int execve(const char *pathname, char *const argv[],char *const envp[]);
int execlp(const char *filename, const char *arg0, ...);
int execvp(const char *filename, char *const argv[]);
/*
 * pathname 和 filename 为空时从当前路径开始搜索文件,
 * 也PATH 环境变量收索BIN文件。
 *
 * execlp 和 execvp 执行的事/bin/sh 脚本不是BIN文件。filename 为输出文件
 * */



/* 改变用户ID和组ID*/
#include <unistd.h>
int setuid(uid_t uid);
int setgid(gid_t gid);

/* BSD支持 交换实际用户ID和有效用户ID的值 */
#include <unistd.h>
int setreuid(uid_t ruid,uid_t euid);
int setregid(gid_t rgid,gid_t egid);

/* 只更改有效哟用户ID和有效组ID */
#include <unistd.h>
int seteuid(uid_t uid);
int setegid(gid_t gid);


#include <stdlib.h>
/* 使用是需要注意权限漏洞,避免在同意进程中于设置权限函数一起使用 */
int system(const char*cmdstring);

/*进程 会记*/
#include <sys/acct.h>
/* 为列入规范中,有平台差异性
 * 当进程结束后会记录关的进行信息,如启动时间,
 * 消耗CPU 时间等信息。*/

/* 结构体 */
/*struct acct ;
ac_flag:
                                        FreeBSD 5.2.1  Linux 2.4.22  Mac OS X 10.3   Solarn 9
AFORK   进程是由fork产生的。但从未调用exec    Y             Y         Y                Y
ASU     进行使用超级用户特权                 N             Y           Y                Y
ACOMPAT 进行使用兼容模式                    N             N           N                N
ACORE   进程转储core                        Y             Y           Y                N
AXSIG   进行由信号杀死                      Y             Y           Y                N
AEXPND  扩展的会记条目                      N             N           N                Y   
*/


/* 用户标示 */
#include <unistd.h>
char *getlogin(void);
/* 成功返回登录信息,失败返回NULL */

/* 进程时间 */
#include <sys/times.h>
clock_t times(struct tms *buf);
/* 成功返回时间,失败返回 -1 */
struct tms{
clock_t tms_utime;/* user CPU time */
clock_t tms_stme; /* system cpu time */
clock_t tms_cutime;/* user CPU time terminated children */
clock_t tms_cstime;/* system CPU time ,terminated children*/
};


/* 进程组 */
#include  <unistd.h>
/* 返回进行的进程组ID */
pid_t getpgrp(void);

pid_t getpgid(pid_t pid);
/* pid =0  等同于调用  getpid();  成功返回组ID,失败返回-1*/

int setpgid(pid_t pid,pid_t pgid);
/* 成功返回0 失败返回-1
  如果 pid = pgid  这pid 的ID将变成这个组的组长
*/



/* 会话 (session) : 是多个进程组的集合 */
#include <unistd.h>
pid_t setsid(void); /* 成功返回进程组ID 失败返回-1*/

pid_r getsid(pid_t pid); /* 取得会话ID 成功返回首进程的进程组ID,失败返回-1 */
/* pid =0 返回进行的会话首进行的进程组ID 有权限限制可能失败 */


/* 控制终端 */
#include <unistd.h>
pid_t tcgetpgrp(int fileds);/* 成功返回前台进程组ID,失败返回-1 */
int tcsetpgrp(int filedes, pid_t pgrpid); /* 成功返回0 , 失败返回-1 */

#include  <termios.h>
pid_t tcgetsid(int filedes); /* 成功返回会话首进程的进程组ID 失败返回-1 */


/* 作业控制 */
/*
1 支持作业控制的shell
2 内核中的终端驱动程序必须支持作业控制
3 内核必须提供对某些作业控制信号的支持

中断字符  Ctrl + C SIGINT
退出字符  Ctrl + \ SIGQUIT
挂起字符  Ctrl + Z SIGTSTP

*/


/* 孤儿进程 */
/*                          

孤儿进程 精灵进程     
编程规则
1 首先做的是调用fork,然后使用父进程exit。
第一点如果该精灵进程是由一条简单的shell命令启动的。那么使父进程终止使得shell认为这条命令执行完成。
第二点只进程继承了父进程的进程组ID,但具有一个新的进程ID,这就保证了子进程不是一个进程组的首进程,
2 调用setsid以创建一个新的对话期。
3 将当前工作目录改为根目录。如果精灵进程的当前工作目录在一个装备文件系统中,那么该文件系统就不能被卸载。
4 将文件方式创建屏蔽字设置为0。 若精灵进程要创建一个组可读,写的文件,而集成的文件方式创建屏蔽字,屏蔽了这两种许可权,这所要求的组可读,写就不能起作用。
5 关闭不再需要的文件描述符。这样使精灵进程就不再持有从其父进程继承来的末写文件描述符。
                                                         
                                                         
一个进程的父进行以终止,的子进程成为孤儿进程被init 所收养
session 结构 
s_count  是该会话中的进程组数,当此计数器减到0时释放该结构
s_leader 是指向会话首进程proc结构的指针
s_ttyvp  是指向控制终端vnode结构指针
s_ttyp   是指向控制终端tty结构指针
s_sid    是会话ID,请记住会话ID这一概念并非Sigle UNIX Specification 的组成部分

tty 结构
t_session 指向将此终端作为控制终端的session结构
t_pgrp    指向前台进程组的pgrp结构,终端驱动程序用此字段将信号送至前台进程。
t_tremios 是包含所有这些特殊字符以及于该终端有关信息
t_winsize 是包含终端窗口当前尺寸的winsize结构,改变窗口尺寸是发送SIGWINCH信号

pgrp 结构
pg_id 是进程ID
pg_session 指向此进程组成员会话session结构
pg_members 是指向作为此进程组成员的proc结构列表指针。 proc 是双向链表

proc 结构
p_pid 包含进程ID
p_pptr 是指向父进程proc结构的指针
p_pgrp 是指向本进程所有组的pgrp结构指针


 信号 
-------------------------------------------------------------------------------------------------------
名字       说明               ISO C    SUS    FreeBSD    Linux   Mac OS X     Solaris        默认动作
-------------------------------------------------------------------------------------------------------
SIGABRT    异常终止(abort)   Y           Y        Y        Y         Y             Y         终止+ code
SIGALRM    异常终止(alarm)   N           Y        Y        Y         Y             Y         终止
SIGBUS     硬件故障              N           Y        Y        Y         Y             Y         终止+ code
SIGCACEL   线程内部使用        N           N        N        N         N             Y         忽略
SIGCHLD    子进程状态改变      N           Y        Y        Y         Y             Y         忽略
SIGCONT    使暂停进程继续      N           Y        Y        Y         Y             Y         继续/忽略
SIGEMT     硬件故障       N           N        Y        Y         Y             Y         终止+ code
SIGFPE     算数异常             Y           Y        Y        Y         Y             Y         终止+ code
SIGFREEZE  检查点冻结      N           N        N        N        N             Y         忽略
SIGHUP     链接断开        N           Y        Y        Y         Y             Y         终止
SIGILL     非法硬件指令      Y           Y        Y        Y         Y             Y         终止+ code
SIGINFO    键盘状态请求      N           N        Y        N         Y             N         忽略
SIGINT     终端中断符         Y           Y        Y        Y         Y             Y         终止
SIGIO      异步I/O               N            N        Y        Y         Y             Y         终止/忽略
SIGIOT     硬件故障         N            N        Y        Y         Y             Y         终止+ code
SIGKILL    终止                N            Y        Y        Y         Y             Y         终止
SIGLWP     线程库内部使用      N            N        N        N         N             Y         忽略
SIGPIPE    写至无读进程的管道    N           Y       Y        Y         Y             Y         终止
SIGPOLL    可轮询事件(poll)   N           XSI    N        Y         N             Y         终止
SIGPROF    时间超时(settimer ) N           XSI        Y        Y         Y             Y         终止
SIGPWR     电源失效/重启       N           N        N        Y         N             Y         终止/忽略
SIGQUIT    终端退出符           N           Y        Y        Y         Y             Y         终止+ code
SIGSEGV    无效内存引用       Y           Y        Y        Y         Y             Y         终止+ code
SIGSTKFLT  协处理器栈故障      N           N        N        Y         N             N         终止
SIGSTOP    停止          N           Y        Y        Y         Y             Y         暂停进程
SIGSYS     无效系统调用      N           XSI    Y        Y         Y             Y         终止+ code
SIGTERM    终止          Y           Y        Y        Y         Y             Y         终止
SIGTHAW    检查点解冻       N           N        N        N         N             Y         忽略
SIGTRAP    硬件故障        N           XSI    Y        Y         Y             Y         终止+ code
SIGTSTP    终端停止符       N           Y        Y        Y         Y             Y         暂停进程
SIGTTIN    后台读控制tty       N           Y        Y        Y         Y             Y         暂停进程
SIGTTOU    后台写至控制tty     N           Y        Y        Y         Y             Y         暂停进程
SIGURG     紧急情况(套接字)    N           Y        Y        Y         Y             Y         忽略
SIGUSR1    用户定义的信号    N           Y        Y        Y         Y             Y         终止
SIGUSR2    用户定义的信号     N           Y        Y        Y         Y             Y         终止
SIGVTALRM  虚拟时间闹钟     N            XSI    Y        Y         Y             Y         终止
SIGWAITING 线程库内部使用     N            N        N        N         N             Y         忽略
SIGWINCH   终端窗口大小改变    N            N        Y        Y         Y             Y         忽略
SIGGXCPU   超过CPU限制        N            XSI        Y        Y         Y             Y         终止+ code/忽略
SIGXFSZ    超过文件长度限制    N           XSI        Y        Y         Y             Y         终止+ code/忽略
SIGXRES    超过资源控制      N           XSI        N        N         N             Y         忽略

SIGABRT
调用abort 函数时产生这个信号,进程异常终止。

SIGALRM 
在用alarm函数设置的计时器超时时,产生信号,
若由setitimer(2)函数设置的间隔时间超时时,也会产生此信号。

SIGBUS
指示一个实现定义的硬件故障,当出现某些类型的内存故障时,
实现常常产生此信号。

SIGCANCEL 
是Solarisx线程库内不使用的信号,不共一般应用。

SIGCHLD
在一个进程终止或停止时,将SIGCHLD信号发送给其父进程,按系统默认。
将忽略此信号,如果父进程希望被告知其子进程的这种状态改变,则应捕获此信号
信号捕获函数中通常要调用一种wait函数以取得子进程ID和其终止状态。




线程

线程标示
*/

#include <pthread.h>
int pthread_equal(pthread_t tid1,pthread_t tid2); // 返回值 : 相等返回非0值,否则返回0
// POSIX  线程的特征测试是_POSIX_THREADS 应用程序可以把这个宏定于#ifdef测试,以在编译时确定是否支持线程。
// 也可以把_SC_THREADS常数用于调用sysconf函数,从而在运行时确定是否支持线程。
#include <pthread.h>
ptherad_t ptherad_self(void); // 返回值 : 返回调用线程的ID。

/*  线程创建   */
#include <pthread.h>
int  pthread_create(pthread_t *restrict tidp,coust pthread_attr_t *restrict attr,void *(*start_rtn)(void),void *restrict arg );
// 返回值 : 当成功返回时,由tidp指向的内存单元被设置为新创建的进程的线程ID。attr参数用于定制各种不同的线程属性。
// 可以设置为NULL 创建默认属性的线程。
// 新创建的线程在start_rtn函数地址开始执行,该函数只有一个无类型的指针参数arg,如果需要向start_rtn函数传递的阐述不止一个,那么需要参数
// 放到结构体中。通过arg 传递给线程处理。
// pthread函数调用失败时不会返回errno 代码。

/*线程终止
1 线程只有从启动历程三种方式退出,返回值是线程的腿出码。
2 线程可以被同一进程中的其他线程取消。
3 线程调用pthread_exit.       */

#include <pthread.h>
void pthread_exit(void *rval_ptr);
//rval_ptr 是一个无类型指针,与传给启动历程的单个参数类似。进程中的其他线程可以通过调用pthread_join函数访问到这个指针。
#include <pthread.h>
int pthread_join(pthread_t thread,void **rval_ptr);
//返回值:若成功则返回0,否则返回错误编号。调用线程将一直阻塞,直到指定的线程调用pthread_exit,从启动历程中返回或者被取消。

// 调用 pthread_cancle 函数来请求取消同一进程中的其他进程。
#include <pthread.h>
int pthread_cancle(pthread_t tid);
// 返回值:若成功则返回0,否则返回错误号
// 默认情况下,pthread_cancle 函数会使得由tid标示的线程的行为表现为如同调用了参数为PTHREAD_CANCELED 的 pthread_exit 函数,但是
// 线程可以选择忽略取消方式或是控制取消方式。

/* 进程栈操作 */         

#include <pthread.h>
void pthread_cleanup_push(void (*rtn)(void *),void *arg);ei
void pthread_cleanup_pop(int execute);
/*
当线程执行一下动作时调用清理函数调用参数为arg,清理函数rtn的调用顺序是由,pthread_cleanup_push函数来安排的 。
1 调用pthread_exit 时
2 响应取消请求。
3 用非零execute 参数调用pthread_cleanup_pop时。
如果 execute =0 清理函数将不被调用。无论那种情况 pthread_cleanup_pop都将删除上次pthread_cleanup_push调用建立的清理处理程序。

注意: 函数有限制,由于他们可以实现为宏。所以必须在与线程相同的作用域中以匹配对应的形式。


进程原于线程原语比较                      
-------------------------------------------
进程          线程                  描述  
-------------------------------------------
fork            pthread_create      创建新的控制流
exit           pthread_exit        从现在的控制流中退出
waitpid      pthread_join        从控制流中得到退出状态
atexit       pthread_cancle_push 注册在退出控制流时调用的函数
getpid       pthread_self        获取控制流ID
abort        pthread_cancle      请求可控制流的非正常退出


线程进入分离状态
分离状态:进程的终止状态会保存到该线程调用的pthread_join,如果线程已经处于分离状态,线程的地称存粗资源可以在线程终止时立即被回收。
*/

#include <pthread.h>
int pthread_detach(pthread_t tid);
//返回值: 成功返回0,错误返回错误号

/*
线程同步
1互斥量
可以通过使用pthread的互斥接口保护数据,确保同一时间只有一个线程访问数据。
需要声明互斥量
pthread_mutex_t 数据类型进行初始化。
PTHREAD_MUTEX_INITIALIZER 进行初始化。
pthread_mutex_t   abc = PTHREAD_MUTEX_INITIALIZER;
*/

#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr-t *restrict attr);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
//成功返回0 失败返回错误编号。
/*
采用默认属性初始化互斥变量,只要把attr设置为NULL。


互斥变量加锁
*/

#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
//成功返回0 失败返回错误代码。
/*
如果不希望新城被阻塞,可以调用pthread_mutex_trylock尝试加锁 ,如果以被加上锁这返回EBUSY。否则返回0.

2避免死锁


读写锁
条件锁
*/
 



/*
 高级进程间通信 IPC 
 通信方式有 管道 FIFO 消息队列 信号量 共享存储 等几种方式。
 
1 管道
管道一个双工(全双工)管道。管道是一种流设备,故可以将处理模块压入管道的人一一端。
 
SVR4 下的s_pipe 函数     
*/

#include <unistd.h>
int pipe(int filedes[2]);//返回:成功0 出错为0


/*
@ popen 和pclose 函数   
创建一个链接到另一个进程的管道
*/

#include <stdio.h>
FILE *popen(const char *cmdstring, const char *type);
//返回:成功返回文件指针,错误为NULL       
/* 
cmdstring 为shell 命令
type 取值为 r w 
*/

int pclose(FILE *fp);
//返回:cmdstring 的终止状态,若出错则为-1 
/*
@ FIFO 命名管道
*/

#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char parthname,mode_tmode );
// 返回: 若成功返回0 失败返回-1
/*
一旦用mkfifo 创建了一个FIFO 就可以open它,( close ,read , write , unlink 等)都可用于FIFO。
O_NONBLOCK 非阻塞标记


FIFO 用途:
1 FIFO由shell使用以便将数据从一条管道线传入另一条,为无需创建中间临时文件。
mkfifo fifo1
prog3 < fifo1 &
prog1 < infile  | tee fifo1 | prog2  
创建FIFO,然后在后台启动prog3,它从FIFO读数据。然后启动p读prog1,用tee其输出发送到FIFO和prog2。

2 FIFO客户机-服务器应用程序中,以在客户机和服务器之间传递数据。

消息队列
从消息队列中取消息。
*/

#include  <sys/types.h>
#include  <sys/ipc.h>
#include  <sys/msg.h>
int msgget(key_t key,int flag);
//返回:若成功返回消息ID,错误返回-1。

/*
msgctl函数对队列执行多种操作。
*/

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgctl(int msqid,int cmd,struct msqid_ds buf);
//返回:成功返回0错误返回-1
/*
cmd 参数指定对于由msqid的队列要执行的命令:
1 IPC_STAT 取此队列的msqid_ds 结构,并将其存放在buf指向的结构中。
2 IPC_SET  按由buf的结构中的值,设定与此队列相关的结构中的下列4个字段:
msg_perm.uid 
msg_perm.gid
msg_perm
mode 
msg_qbytes 
此命令只能由下列两种进程执行:
一种是其有效用户ID等于msg_perm.cuid或msg_perm.uid;
另一种是具有超级用户特权的进程。只有超级用户才能加msg_qbytes的值
3 IPC_RMID 从系统中删除该消息队列以及仍在该队列上的所有数据。为立即生效。
重复删除一条消息时返回EIDRM。
此命令只能有下列两种进程执行:
一种是其有效用户ID等于msg_perm.cuid 或msg_perm.uid 
另一种是具有超级用户特权的进程。

 IPC_STAT ,IPC_SET ,IPC_RMID  也可以用户共享内存。
 

将消息插入到消息队列中   
*/

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid,const void ptr,size_t nbytes, int flag);
//返回:成功返回0 ,错误返回-1


/*
从消息队列中取出消息   
*/

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgrcv(int msqid,void ptr,size_t nbytes,long type,int flag);
//返回:成功返回消息数据长度,错误返回-1
/*
ptr  参数指向一个长整型数,nbytes说明数据缓存长度。若返回的消息大于nbytes,而且在flag中设置了MSG_NOERROR,则
该消息被截断。
type 参数
=0 返回队列中的第一条消息
>0 返回队列中的消息类型为type的第一个消息。
<0 返回队列中消息类型值小于或等于type绝对值。而且在这种消息中,其类型值又最小的消息。
非0 type 用于以非先进献出次序读消息。


信号量
信号量是一个计数器。用于进程对共享数据对像的存储。流程如下:

1 测试控制该资源的信号量。
2 若此信号量为正值,则进程可以使用该资源。进程将信号值减1,表示它使用了一个资源单位。
3 若此进程信号量的值为0 ,则进程进入睡眠状态,知道信号量值大于0。若进程被唤醒后,返回第一步。

影响信号量的系统限制
-------------------------------------------
名称   说明                            典型值
-------------------------------------------
SEMVMX 任一信号量的最大值            32767
SEMAEM 任一信号量的最大终止时调整值   16384
SEMMNI 系统中信号量集的最大数         10
SEMMNS 系统中信号量集的最大数         60
SEMMSL 每个信号量集中的最大信号量数    25
SEMMNU 系统中undo结构的最大数         30
SEMUME 每个undo结构中的最大undo项数    10
SEMOPM 每个semop调用所包含的最大操作数 10  
*/


/*
获取一个信号量ID.
*/

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key_t key,int nsems,int flag);
//返回:成功返回信号量ID,出错返回-1

/*
信号量的多种操作
*/

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semctl(int semid,int semnum,int cmd,union semurarg);
/*semurarg 是联合,而非指向联合的指针
union semun{
    int val; //for SETVAL 
    struct semid_ds *buf;//for IPC_STAT and IPC_SET 
    ushort *array; // for GETALL and SETALL 
    }
cmd 有10中命令
IPC_STAT 对此集合取semid_ds结构,并存放在由arg.buf指向的结构中。
IPC_SET  按由arg.buf 指向的结构中的值设置与此集合相关结构中的下列3个字段值:
sem_perm.uid,sem_perm.gid和sem_perm.mode 。此命令只能由下列两种进程执行:一种是其有效用户ID等于sem_perm.cuid或sem_perm.uid 
的进程,另一种是具有超级用户特权的进程。
IPC_RMID 从系统中删除该信号量集合。
GETVAL 返回成员semnum的semval值。
SETVAL 设置成员semnum的semval值。该值由arg.val指定。
GETPID 返回成员semnum的sempid值。
GETNCNT 返回成员semnum的semncnt值。
GETZCNT 返回成员semnum的semzcnt值。
GETALL 取该集合中的所有信号量的值,并将它们存放在由arg.array的数组中。
SETALL 按arg.array指向的数据组中的值设置该集合中所有信号量的值。

自动执行信号量集合上的操作数组。
*/

#include  <sys/types.h>
#include  <sys/ipc.h>
#include  <sys/sem.h>
int semp(int semid,struct sembuf semoprarray[],size_t nops);
/*返回:成功为0,失败为-1
semoprarray 是个指针指向信号量的操作数组。
struct sembuf{
    ushort sem_num;//member # in set (0,...1,,nsems-1 )
    short  sem_op; //operation (negative,0 ,or pasitive)
    short  sem_flg;//IPC_NOWAIT,SEM_UNDO
    }
sem_op :可以取负值、0或正值。
1 取正值,返回进程占用的资源。
2 取负值,表示要获取由该信号量控制的资源。若信号量的值大于或等于sem_op绝对值,则从信号量值中减去
sem_op的绝对值。这保证信号量的结果值大于活等于0。如果指定了undo标志,这sem_op的绝对值也加到该进程的此信号量调整值上。
如果信号量值小于sem_op绝对值
    a 若指定了IPC_NOWAIT ,则出错返回EAGAIN;
    b 若未指定IPC_NOWAIT ,这该信号量的semncnt值加1 进入睡眠状态,然后调用进程被挂起直至下列事件之一发生:

        i 此信号量变成大于或等于sem_op的绝对值 (某个进程已是放了某些资源),此信号量的semncnt值减1 (进程结束等待),
        并信号量值中减去sem_op的绝对值。如果指定了undo标示,则sem_op绝对值也加到该进程的此信号量调整值上。
        ii 从系统中删除此信号量。在此情况下函数出错返回ERMID.
        iii 进程捕捉到一个信号,并从信号处理程序返回。信号量的semncnt 值减1  不在等待 并返回错误EINTR.
3 若sem_op为0, 这表示希望等待到该信号量编程0,如果信号量值当前是0 ,此时函数立即返回。
如果非0 则:
  a 若指定了IPC_NOWAIT,则出错返回EAGAIN;
  b 若末个指定IPC_NOWAIT ,则该信号量的semncnt值加1 将进入 睡眠状态,然后调用进程被挂起,直至下一列事件之一发生:
    i   此信好量值变成0.此信号量的semzcnt值减1 (已经结束等待)。
    ii  从系统中删除了此信号量。在此情况下,函数出错返回ERMID。
    iii 进程捕捉到一个信号,并从信号处理程序返回。在此情况下 ,此信号量的semzcnt 值减1 (因不在等待),并且函数返回EINTR.
nops 规定该数据中操作的数量(元素数)。   
   
   
共享内存
共享内存结构体
struct shmid_ds{
    struct ipc_perm shm_perm;// see section 14.6.2
    struct anon_map *shm_amp;// pointer in keernel 
    int shm_segsz;    //size of segment in bytes 
    ushort shm_lkcnt; //number of times segment is being locked 
    pid_t  shm_lpid;  //pid of last shmop()
    pid_t  shm_cpid;  //pid of creator 
    ulong  shm_nattch;//number of current attaches  
    ulong  shm_cnattch;//used onlg for shminfo 
    time_t shm_atime; //last-attach time 
    time_t shm_dtime; //last-detach time 
    time_t shm_ctime; //last-change time 
    }
   
获得一个共享存储标识符。
*/

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key,int size,int flag);
/*
返回:成功返回共享内存ID,失败返回-1
影响共享存储的系统限制

-------------------------------------------
名称      说明                        典型值
-------------------------------------------
SHMMAX  共享存储段的最大字节数         131072
SHMMIN  共享存储段的最小字节数          1
SHMMNI  系统中共享存储段的最大段数     100
SHMSEG  每个进程,共享存储段的最大段数  6

共享存储段执行多种操作
*/

#include  <sys/types.h>
#include  <sys/ipc.h>
#include  <sys/shm.h>
int shmctl(int shmid,int cmd,struct shmid_ds *buf)
/*返回:若成功为0 错误为-1

cmd  5 种,在shmid 指定的端上执行。
IPC_STAT 对此段取shmid_ds结构并存放在buf指的结构中。
IPC_SET  按buf 指向结构中的值设置此段相关结构如下
shm_perm.uid  shm_perm.gid  shm_perm.mode 此命令只能有下两种进程执行、:一种是shm_perm.cuid
shm_perm.uid, 另一种是超级用户权限。
IPC_RMID 删除系统共享存储段
SHM_LOCK 锁住共享存储段。超级用户执行。
SHM_UNLOCK 解锁共享存储段。超级用户执行。

得到共享存储地址空间
*/

#include  <sys/types.h>
#include  <sys/ipc.h>
#include  <sys/shm.h>
void *shmat(int shmid,void *addr, int flag);
/*
返回:成功返回指向共享存储段指针,出错返回-1
addr 参数在flag是否能指定SHM_RND 为有关。
addr 取值:
1 如果addr =0 ,则此段连接到由内核选择的第一个可选地址上。
2 如果addr !=0 ,并没有设定SHM_RND,则此段链接到addr知道地址上。
3 如果addr !=0 ,并指定了SHM_RND,则此段链接到(addr - (addr mod SHMLBA)) 上所指的地址上。
SHM_RND 意思是:取整 ,SHMLBA 意识是:低边界地址倍数它总是2 的乘方。

结束操作共享存储,调用shmdt脱接该段。并不是从系统中删除其标识符以及其数据结构。
直到某个进程调用shmctl(待IPC_RMID) 特地删除它。
*/

#include  <sys/types.h>
#include  <sys/ipc.h>
#include  <sys/shm.h>
int shmdt(void *addr)
/*
返回:成功返回0 出错返回-1

多个进程映射共享存储空间 4.3+BSD特征
caddr_t area;
if(( area = mmap(0,SIZE ,PROT_READ | PROT_WRITE,MAP_ANON | MAP_SHARED, -1,0)) == (cadder_t) -1)
*/


阅读(2228) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

小蝌蚪1232012-04-19 21:48:21

哇,多好的博文,博主很不错啊,真的辛苦了。。多谢分享啊