Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1753345
  • 博文数量: 600
  • 博客积分: 10581
  • 博客等级: 上将
  • 技术积分: 6205
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-06 10:13
文章分类
文章存档

2016年(2)

2015年(9)

2014年(8)

2013年(5)

2012年(8)

2011年(36)

2010年(34)

2009年(451)

2008年(47)

分类: C/C++

2009-08-22 13:12:04

 . shm_perm.cgidshm_perm.gid设置为调用进程的有效GID.
             . shm_perm.mode访问权限比特位设置为shmflg访问权限比特位.
             . shm_lpid,shm_nattch,shm_atime,shm_dtime设置为0.
             . shm_ctime设置为当前系统时间.
             . shm_segsz设置为0.
        返回值:若调用成功则返回一个非0,称为共享内存标识符,否则返回
             值为-1.
    20.shmctl()
        功能:共享内存控制操作.
        语法:#include 
             #include 
             #include 
             int shmctl(shmid,cmd,buf)
             int shmid,cmd;
             struct shmid_ds *buf;
        说明:本系统调用提供一系列共享内存控制操作.操作行为由cmd指定.
             以下为cmd的有效值:
             . IPC_STAT:shmid相关的数据结构中各个元素的当前值放入由
                 buf指向的结构中.
             . IPC_SET:shmid相关的数据结构中的下列元素设置为由buf
                 向的结构中的对应值.
                 shm_perm.uid
                 shm_perm.gid
                 shm_perm.mode
                 本命令只能由有效UID等于shm_perm.cuidshm_perm.uid
                 进程或有效UID有合适权限的进程操作.
             . IPC_RMID:删除由shmid指示的共享内存.将它从系统中删除并
                 破坏相关的数据结构.
                 本命令只能由有效UID等于shm_perm.cuidshm_perm.uid
                 进程或有效UID有合适权限的进程操作.
        返回值:若调用成功则返回0,否则返回-1.
        例子:本例包括上述所有共享内存操作系统调用:
             #include 
             #include 
             #include 
             #define SHMKEY 74
             #define K 1024
             int shmid;
             cleanup()
             {
                 shmctl(shmid,IPC_RMID,0);
                 exit(0);
             }
             main()
             {
                 int *pint;
                 char *addr1,*addr2;
                 extern char *shmat();
                 extern cleanup();
                 for (i=0;i<20;i++)
                     signal(i,cleanup);
                 shmid=shmget(SHMKEY,128*K,0777|IPC_CREAT);
                 addr1=shmat(shmid,0,0);
                 addr2=shmat(shmid,0,0);
                 printf("addr1 0x%x addr2 0x%x\n",addr1,addr2);
                 pint=(int*)addr1;
                 for (i=0;i<256;i++)
                     *pint++=i;
                 pint=(int*)addr1;
                 *pint=256;
                 pint=(int*)addr2;
                 for (i=0;i<256;i++)
                     printf("index %d\tvalue%d\n",i,*pint++);
                 shmdt(addr1);
                 shmdt(addr2);
                 pause();
             }
    21.semctl()
        功能:信号量控制操作.
        语法:#include 
             #include 
             #include 
             int semctl(semid,memnum,cmd,arg)
             int semid,semnum,cmd;
             union semun {
                   int val;
                   struct semid_ds *buf;
                   ushort *array;
             }arg;
        说明:本系统调用提供了一个信号量控制操作,操作行为由cmd定义,
             些命令是对由semidsemnum指定的信号量做操作的.每个命令都
             要求有相应的权限级别:
             . GETVAL:返回semval的值,要求有读权限.
             . SETVAL:设置semval的值到arg.val.此命令成功执行后,
                  semadj的值对应的所有进程的信号量全部被清除,要求有修
                  改权限.
             . GETPID:返回sempid的值,要求有读权限.
             . GETNCNT:返回semncnt的值,要求有读权限.
             . GETZCNT:返回semzcnt的值,要求有读权限.
             以下命令在一组信号量中的各个semval上操作:
             . GETALL:返回每个semval的值,同时将各个值放入由arg.array
                 指向的数组中.当此命令成功执行后,semadj的值对应的所有
                 进程的信号量全部被清除,要求有修改权限.
             . SETALL:根据由arg.array指向的数组设置各个semval.当此
                 命令成功执行后,semadj的值对应的所有进程的信号量全部
                 被清除,要求有修改权限.
             以下命令在任何情况下都是有效的:
             . IPC_STAT:将与semid相关的数据结构的各个成员的值放入由
                 arg.buf指向的结构中.要求有读权限.
             . IPC_SET:设置semid相关数据结构的如下成员,设置数据从
                 arg.buf指向的结构中读取:
                   sem_perm.uid
                   sem_perm.gid
                   sem_perm.mode
                 本命令只能由有效UID等于sem_perm.cuidsem_perm.uid
                 进程或有效UID有合适权限的进程操作.
             . IPC_RMID:删除由semid指定的信号量标识符和相关的一组信号
                 量及数据结构.本命令只能由有效UID等于sem_perm.cuid
                 sem_perm.uid的进程或有效UID有合适权限的进程操作.
        返回值:若调用成功,则根据cmd返回以下值:
               GETVAL:semval的值.
               GETPID:sempid的值.
               GETNCNT:semncnt的值.
               GETZCNT:semzcnt的值.
               其他:0.
               若调用失败则返回-1.
    22.semget()
        功能:取得一组信号量.
        语法:#include 
             #include 
             #include 
             int semget(key,nsems,semflg)
             key_t key;
             int nsems,semflg;
        说明:返回和key相关的信号量标识符.
             若以下事实成立,则与信号量标识符,与之相关的semid_ds数据结
             构及一组nsems信号量将被创建:
               . key等于IPC_PRIVATE.
               . 系统内还没有与key相关的信号量,同时(semflg&IPC_CREAT)
                 为真.
             创建时新的信号量相关的semid_ds数据结构被初始化如下:
             . 在操作权限结构,sem_perm.cuidsem_perm.uid设置等于调用
               进程的有效UID.
             . 在操作权限结构,sem_perm.cgidsem_perm.gid设置等于调用
               进程的有效GID.
             . 访问权限比特位sem_perm.mode设置等于semflg的访问权限比
               特位.
             . sem_otime设置等于0,sem_ctime设置等于当前系统时间.
        返回值:若调用成功,则返回一非0,称为信号量标识符;否则返回-1.
    23.semop()
        功能:信号量操作.
        语法:#include 
             #include 
             #include 
             int semop(semid,sops,nsops)
             int semid;
             struct sembuf *sops;
             unsigned nsops;
        说明:本系统调用用于执行用户定义的在一组信号量上操作的行为集合.
             该组信号量与semid相关.
             参数sops为一个用户定义的信号量操作结构数组指针.
             参数nsops为该数组的元素个数.
             数组的每个元素结构包括如下成员:
               sem_num;    /* 信号量数 */
               sem_op;     /* 信号量操作 */
               sem_flg;    /* 操作标志 */
             由本系统调用定义的每个信号量操作是针对由semidsem_num
             定的信号量的.变量sem_op指定三种信号量操作的一种:
             . sem_op为一负数并且调用进程具有修改权限,则下列情况之
               一将会发生:
               * semval不小于sem_op的绝对值,sem_op的绝对值被减去
                 semval的值.(semflg&SEM_UNDO)为真则sem_op的绝对值加
                 上调用进程指定的信号量的semadj.
               * semval小于sem_op的绝对值同时(semflg&IPC_NOWAIT)
                 ,则本调用立即返回.
               * semval小于sem_op的绝对值同时(semflg&IPC_NOWAIT)
                 ,则本系统调用将增加指定信号量相关的semncnt(加一),
                 将调用进程挂起直到下列条件之一被满足:
                   (1).semval值变成不小于sem_op的绝对值.当这种情况发
                       生时,指定的信号量相关的semncnt减一,
                       (semflg&SEM_UNDO)为真则sem_op的绝对值加上调用
                       进程指定信号量的semadj.
                   (2).调用进程等待的semid已被系统删除.
                   (3).调用进程捕俘到信号,此时,指定信号量的semncnt
                       减一,调用进程执行中断服务程序.
             . sem_op为一正值,同时调用进程具有修改权限,sem_op的值加
               semval的值,(semflg&SEM_UNDO)为真,sem_op减去调用
               进程指定信号量的semadj.
             . sem_op0,同时调用进程具有读权限,下列情况之一将会发
               :
               * semval0,本系统调用立即返回.
               * semval不等于0(semflg&IPC_NOWAIT)为真,本系统调用
                 立即返回.
               * semval不等于0(semflg&IPC_NOWAIT)为假,本系统调用
                 将把指定信号量的
                 semzcnt值加一,将调用进程挂起直到下列情况之一发生:
                   (1).semval值变为0,指定信号量的semzcnt值减一.
                   (2).调用进程等待的semid已被系统删除.
                   (3).调用进程捕俘到信号,此时,指定信号量的semncnt
                       减一,调用进程执行中断服务程序.
        返回值:调用成功则返回0,否则返回-1.
        例子:本例将包括上述信号量操作的所有系统调用:
             #include 
             #include 
             #include 
             #define SEMKEY 75
             int semid;
             unsigned int count;
             /*在文件sys/sem.h中定义的sembuf结构
              *  struct sembuf {
              *      unsigned short sem_num;
              *      short sem_op;
              *      short sem_flg;
              *  }*/
             struct sembuf psembuf,vsembuf;   /*PV操作*/
             cleanup()
             {
                 semctl(semid,2,IPC_RMID,0);
                 exit(0);
             }
             main(argc,argv)
             int argc;
             char *argv[];
             {
                 int i,first,second;
                 short initarray[2],outarray[2];
                 extern cleanup();
                 if (argc==1) {
                     for (i=0;i<20;i++)
                         signal(i,clearup);
                     semid=semget(SEMKEY,2,0777|IPC_CREAT);
                     initarray[0]=initarray[1]=1;
                     semctl(semid,2,SETALL,initarray);
                     semctl(semid,2,GETALL,outarray);
                     printf("sem init vals %d%d \n",
                            outarray[0],outarray[1]);
                     pause(); /*睡眠到被一软件中断信号唤醒*/
                 }
                 else if (argv[1][0]=='a') {
                     first=0;
                     second=1;
                 }
                 else {
                     first=1;
                     second=0;
                 }
                 semid=semget(SEMKEY,2,0777);
                 psembuf.sem_op=-1;
                 psembuf.sem_flg=SEM_UNDO;
                 vsembuf.sem_op=1;
                 vsembuf.sem_flg=SEM_UNDO;
                 for (count=0;;xcount++) {
                     psembuf.sem_num=first;
                     semop(semid,&psembuf,1);
                     psembuf.sem_num=second;
                     semop(semid,&psembuf,1);
                     printf("proc %d count %d\n",getpid(),count);
                     vsembuf.sem_num=second;
                     semop(semid,&vsembuf,1);
                     vsembuf.sem_num=first;
                     semop(semid,&vsembuf,1);
                 }
             }
    24.sdenter()
        功能:共享数据段同步访问,加锁.
        语法:#include 
             int sdenter(addr,flags)
             char *addr;
             int flags;
        说明:用于指示调用进程即将可以访问共享数据段中的内容.
             参数addr为将一个sdget()调用的有效返回码.
             所执行的动作取决于flags的值:
             . SD_NOWAIT:若另一个进程已对指定的段调用本系统调用且还没
                 有调用sdleave(),并且该段并非用SD_UNLOCK标志创建,则调
                 用进程不是等待该段空闲而是立即返回错误码.
             . SD_WRITE:指示调用进程希望向共享数据段写数据.此时,另一
                 个进程用SD_RDONLY标志联接该共享数据段则不被允许.
        返回值:调用成功则返回0,否则返回-1.
    25.sdleave()
        功能:共享数据段同步访问,解锁.
        语法:#include 
             int sdleave(addr,flags)
             char *addr;
        说明:用于指示调用进程已完成修改共享数据段中的内容.
        返回值:调用成功则返回0,否则返回-1.
    26.sdget()
        功能:联接共享数据段到调用进程的数据空间中.
        语法:#include 
             char *sdget(path,flags,size.mode)
             char *path;
             int flags;
             long size;
             int mode;
        说明:本系统调用将共享数据段联接到调用进程的数据段中,具体动作
             flags的值定义:
             . SD_RDONLY:联接的段为只读的.
             . SD_WRITE:联接的段为可读写的.
             . SD_CREAT:若由path命名的段存在且不在使用中,本标志的作用
                 同早先创建一个段相同,否则,该段根据sizemode的值进程
                 创建.对段的读写访问权限的授予基于mode给的权限,功能与
                 一般文件的相同.段被初始化为全0.
             . SD_UNLOCK:若用此标志创建该段,则允许有多个进程同时访问
                 (在读写中)该段.
        返回值:若调用成功则返回联接的段地址.否则返回-1.
    27.sdfree()
        功能:将共享数据段从调用进程的数据空间中断开联接.
        语法:#include 
             int sdfree(addr)
             char *addr;
        说明:本系统调用将共享数据段从调用进程的数据段的指定地址中分离.
             若调用进程已完成sdenter()的调用,还未调用sdleave()就调用
             本系统调用,sdleave()被自动调用,然后才做本调用的工作.
        返回值:若调用成功则返回联接的段地址.否则返回-1.
    28.sdgetv()
        功能:同步共享数据访问.
        语法:#include 
             int sdgetv(addr)
             char *addr;
        说明:用于同步协调正在使用共享数据段的进程.返回值为共享数据段
             的版本号.当有进程对该段做sdleave()操作时,版本号会被修改.
        返回值:若调用成功,则返回指定共享数据段的版本号,否则返回-1.
    29.sdwaitv()
        功能:同步共享数据访问.
        语法:#include 
             int sdwaitv(addr,vnum)
             char *addr;
             int vnum;
        说明:用于同步协调正在使用共享数据段的进程.返回值为共享数据段
             的版本号.调用进程会睡眠直到指定段的版本号不再等于vnum;
        返回值:若调用成功,则返回指定共享数据段的版本号,否则返回-1.
    30.sbrk()
        功能:修改数据段空间分配.
        语法:char *sbrk(incr)
             int incr;
        说明:用于动态修改调用进程数据段的空间分配.进程将重置进程的分
             段值并分配一个合适大小的空间.分段值为数据段外第一次分配
             的地址.要分配的空间的增加量等于分段值的增加量.新分配的空
             间设置为0.若相同的内存空间重新分配给同一个进程,则空间的
             内容不确定.
        返回值:若成功调用则返回值为0,否则返回-1.
        例子:本例将包括上述共享数据空间操作的所有系统调用:
             char * area1;
             char buf[21];
             int v;
             /*取得或创建一个共享数据空间(系统特殊文件),名字为
               /tmp/area1,长度为640,用户访问权限为0777*/
             area1=sdget("/tmp/area1",SD_WRITE|SD_CREAT,640,0777);
             if ((int)area1==-1) {
                 printf("get share data segment area1 failed\n");
                 exit(1);
             }
             /*取得共享数据段area1的版本号*/
             v=sdgetv(area1);
             /*申请访问共享数据段area1,若已有进程在访问该段则本进程挂
              *,否则进入访问并将该数据段加写锁*/
             sdenter(area1,SD_WRITE);
             /*对共享数据段访问,10a*/
             strcpy(area1,"aaaaaaaaaa");
             /*申请解除访问权限,若已有进程申请访问则激活该进程*/
             sdleave(area1);
             /*进程处理过程*/
             /*等待取共享数据段area1的版本号*/
             sdwaitv(area1,v);
             /*重新申请访问共享数据段area1*/
             sdenter(area1,SD_WRITE);
             /*读取共享数据段中的数据*/
             memcpy(buf,area1,20);
             /*申请解除访问权限,若已有进程申请访问则激活该进程*/
             sdleave(area1);
             printf("the data now in area1 is [%s]\n",buf);
    31.getenv()
        功能:取得指定环境变量值.
        语法:#include 
             #include 
             char *getenv(name)
             char *name;
        说明:本系统调用检查环境字符串(格式如name=value),并在找到有指
             定名字的环境值后,返回指向value字符串的指针.否则返回空指
             .
        返回值:如前述.
        例子:char * value;
             value=getenv("HOME");
             printf("HOME = [%s]\n",value);
             /*将打印出HOME环境变量的值*/
    32.putenv()
        功能:修改或增加环境值.
        语法:#include 
             int putenv(string)
             char *string;
        说明:参数string指向一个字符串,格式如下:
             name=value
             本系统调用将环境变量name等于值value,修改或增加一个环境变
             ,字符串string成为环境的一部分.
        返回值:putenv()不能取得合适的内存空间则返回非0,否则返回0.
        例子:/*父进程处理*/
             putenv("HOME=/home/abcdef");
             putenv("PATH=/bin");
             if (fork()>0)
                 exit(0);   /*父进程退出运行*/
             /*子进程处理*/
             setpgrp();
             /*父进程设置的环境变量已传到子进程*/
             char * value1;
             value1=getenv("HOME");
             value2=getenv("PATH");
             printf("HOME=[%s],PATH=[%s]\n",value1,value2);
             /*将打印出"HOME=/home/abcdef""PATH=/bin"*/
 
阅读(578) | 评论(0) | 转发(0) |
0

上一篇:多进程编程2

下一篇:多进程编程4

给主人留下些什么吧!~~