⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 多进程编程.htm

📁 windows网络编程技术文章
💻 HTM
📖 第 1 页 / 共 5 页
字号:
                 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 <sys/types.h>
             #include <sys/ipc.h>
             #include <sys/sem.h>
             int semctl(semid,memnum,cmd,arg)
             int semid,semnum,cmd;
             union semun {
                   int val;
                   struct semid_ds *buf;
                   ushort *array;
             }arg;
        说明:本系统调用提供了一个信号量控制操作,操作行为由cmd定义,这
             些命令是对由semid和semnum指定的信号量做操作的.每个命令都
             要求有相应的权限级别:
             . 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.cuid或sem_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 <sys/types.h>
             #include <sys/ipc.h>
             #include <sys/sem.h>
             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.cuid和sem_perm.uid设置等于调用
               进程的有效UID.
             . 在操作权限结构,sem_perm.cgid和sem_perm.gid设置等于调用
               进程的有效GID.
             . 访问权限比特位sem_perm.mode设置等于semflg的访问权限比
               特位.
             . sem_otime设置等于0,sem_ctime设置等于当前系统时间.
        返回值:若调用成功,则返回一非0值,称为信号量标识符;否则返回-1.
    23.semop()
        功能:信号量操作.
        语法:#include <sys/types.h>
             #include <sys/ipc.h>
             #include <sys/sem.h>
             int semop(semid,sops,nsops)
             int semid;
             struct sembuf *sops;
             unsigned nsops;
        说明:本系统调用用于执行用户定义的在一组信号量上操作的行为集合.
             该组信号量与semid相关.
             参数sops为一个用户定义的信号量操作结构数组指针.
             参数nsops为该数组的元素个数.
             数组的每个元素结构包括如下成员:
               sem_num;    /* 信号量数 */
               sem_op;     /* 信号量操作 */
               sem_flg;    /* 操作标志 */
             由本系统调用定义的每个信号量操作是针对由semid和sem_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_op为0,同时调用进程具有读权限,下列情况之一将会发
               生:
               * 若semval为0,本系统调用立即返回.
               * 若semval不等于0且(semflg&IPC_NOWAIT)为真,本系统调用
                 立即返回.
               * 若semval不等于0且(semflg&IPC_NOWAIT)为假,本系统调用
                 将把指定信号量的
                 semzcnt值加一,将调用进程挂起直到下列情况之一发生:
                   (1).semval值变为0时,指定信号量的semzcnt值减一.
                   (2).调用进程等待的semid已被系统删除.
                   (3).调用进程捕俘到信号,此时,指定信号量的semncnt值
                       减一,调用进程执行中断服务程序.
        返回值:调用成功则返回0,否则返回-1.
        例子:本例将包括上述信号量操作的所有系统调用:
             #include <sys/types.h>
             #include <sys/ipc.h>
             #include <sys/sem.h>
             #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;   /*P和V操作*/
             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 <sys/sd.h>
             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 <sys/sd.h>
             int sdleave(addr,flags)
             char *addr;
        说明:用于指示调用进程已完成修改共享数据段中的内容.
        返回值:调用成功则返回0,否则返回-1.
    26.sdget()
        功能:联接共享数据段到调用进程的数据空间中.
        语法:#include <sys/sd.h>
             char *sdget(path,flags,size.mode)
             char *path;
             int flags;
             long size;
             int mode;
        说明:本系统调用将共享数据段联接到调用进程的数据段中,具体动作
             由flags的值定义:
             . SD_RDONLY:联接的段为只读的.
             . SD_WRITE:联接的段为可读写的.
             . SD_CREAT:若由path命名的段存在且不在使用中,本标志的作用
                 同早先创建一个段相同,否则,该段根据size和mode的值进程

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -