精华内容
下载资源
问答
  • struct sembuf结构体

    2019-04-19 00:21:54
    sembuf结构体中的元素 struct sembuf{ short sem_num; short sem_op; short sem_flg; }; •sem_num是信号量的编号,如果你的工作不需要使用一组信号量,这个值一般就取为0。 •sem_op是信号量一次PV操作时加减...

    sembuf结构体中的元素

    struct sembuf{
    	short sem_num;
    	short sem_op;
    	short sem_flg;
    };
    
    

    •sem_num是信号量的编号,如果你的工作不需要使用一组信号量,这个值一般就取为0。

    •sem_op是信号量一次PV操作时加减的数值,一般只会用到两个值,一个是“-1”,也就是P操作,等待信号量变得可用;另一个是“+1”,也就是我们的V操作,发出信号量已经变得可用

    •sem_flag通常被设置为SEM_UNDO.她将使操作系统跟踪当前进程对该信号量的修改情况

    原文:https://blog.csdn.net/ruotao923/article/details/75257824

    展开全文
  • 文章目录1,System V IPC - 信号灯2,System V IPC - 信号灯特点3,System V信号灯使用步骤3.1,信号灯创建/打开 semget()3.2,信号灯初始化 ...sembuf结构体定义4,信号灯集/共享内存---示例 1,System V IPC...

    1,System V IPC - 信号灯

    1. 信号灯也叫信号量,用于进程/线程同步或互斥的机制
    2. 信号灯的类型
      ·Posix 无名信号灯
      ·Posix有名信号灯
      ·System V 信号灯
    3. 信号灯的含义
      ·计数信号灯(信号灯的值就是他代表的资源的数量,Posix 无名信号灯/Posix有名信号灯,都是计数信号灯)

    2,System V IPC - 信号灯特点

    1. System V 信号灯是一个或多个计数信号灯的集合
    2. 可同时操作集合中的多个信号灯
    3. 申请多个资源时避免死锁(信号灯在一个集合里,需要的资源同时申请,都满足时资源才能申请到)

    3,System V信号灯使用步骤

    1. 打开/创建信号灯 semget
    2. 信号灯初始化 semctl
    3. P/V操作 semop
    4. 删除信号灯 semctl

    3.1,信号灯创建/打开 semget()

    #include <sys/ipc.h>
    #include <sys/sem.h>
    int semget(key_t key, int nsems, int semflg);

    1. 成功时返回信号灯的id,失败时返回-1
    2. key 和信号灯关联的key IPC_PRIVATE 或 ftok
    3. nsems 集合中包含的计数信号灯个数
    4. semflg 标志位 IPC_CREAT|0666 IPC_EXCL(通常和IPC_CREAT一起使用,加上IPC_EXCL,如果信号灯存在,则报错)

    信号灯在使用之前必须初始化,且只能初始化一次,通常第一个进程初始化,后面的进程就不能初始化了。

    if((semid = semget(key,3,IPC_CREAT|0666|IPC_EXCL)) < 0)
    {
    	if(errno == EEXIST)
    	{
    		semid = semget(key,3,IPC_CREAT|0666)
    	}
    }
    else
    {
    	初始化信号灯集;
    }
    

    3.2,信号灯初始化 semctl()

    #include <sys/ipc.h>
    #include <sys/sem.h>
    int semctl(int semid, int semnum, int cmd, …);

    1. 成功时返回0,失败时返回EOF
    2. semid 要操作的信号灯集id
    3. semnum 要操作的集合中的信号灯编号
    4. cmd 执行的操作 SETVAL(设置信号灯值) IPC_RMID(删除整个信号灯集)
    5. union semun 取决于cmd(SETVAL需要用到第四个参数,IPC_RMID不需要第四个参数),该共用体需要用户自己定义

    系统中union semun 共用体参考

    union semun {union semun {
       	int              val;    /* Value for SETVAL *///信号量初始值
       	struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
       	unsigned short  *array;  /* Array for GETALL, SETALL */
       	struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                              (Linux-specific) */
              };
    

    3.2.1,信号灯初始化—示例

    要求:假设信号灯集合中包含两个信号灯;第一个初始化为2,第二个初始化为0

    union  semun  myun;
    
    myun.val = 2;
    if (semctl(semid, 0, SETVAL, myun) < 0) 
    {
    	perror(“semctl”);     exit(-1);
    }
    myun.val = 0;
    if (semctl(semid, 1, SETVAL, myun) < 0) 
    {
    	perror(“semctl”);     exit(-1);
    }
    

    3.3,信号灯P/V操作 semop()

    #include <sys/ipc.h>
    #include <sys/sem.h>
    int semop(int semid, struct sembuf *sops, unsigned nsops);

    1. 成功时返回0,失败时返回-1
    2. semid 要操作的信号灯集id
    3. sops 描述对信号灯操作的结构体(数组)
    4. nsops 要操作的信号灯的个数(一次操作sops数组里的前nsops个元素)

    3.3.1,信号灯操作 sembuf结构体定义

    struct  sembuf 
     {
         short  sem_num;
         short  sem_op;
         short  sem_flg;
     };
    
    1. semnum 信号灯编号
    2. sem_op -1:P操作 1:V操作 (也可以让信号数量增加或减少多个,将“1”换成“n”)
    3. sem_flg 0(阻塞方式) / IPC_NOWAIT
    假设当前信号灯集合中有3个信号灯(意味着最多可以同时操作3个信号灯),编号:0,1,2
    现在同时对编号为0和2的信号灯进程P操作
    struct  sembuf buf[3];//结构体数组的大小应该和信号灯集中信号灯的数目保持一致
    buf[0].sem_num = 0;
    buf[0].sem_op = -1;
    buf[0].sem_flg = 0;
    buf[1].sem_num = 2;
    buf[1].sem_op = -1;
    buf[1].sem_flg = 0;
    semop(semid,&buf,2);//2表示依次取出buf中的前两个元素进行操作
    

    4,信号灯集/共享内存—示例

    要求:父子进程通过System V信号灯同步对共享内存的读写
    ·父进程从键盘输入字符串到共享内存
    ·子进程删除字符串中的空格并打印
    ·父进程输入quit后删除共享内存和信号灯集,程序结束

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <sys/sem.h>
    
    #define N 64  	//共享内存大小
    #define READ 0	//可读缓冲区(个数)信号灯在信号灯集合中的编号为0
    #define WRITE 1	//可写缓冲区(个数)信号灯在信号灯集合中的编号为1
    
    union semun{
    	int val;
    	struct semid_ds *buf;
    	unsigned short *array;
    	struct seminfo * __buf;
    };
    void init_sem(int semid,int s[],int n);
    void sem_pv(int semid,int num,int op);
    
    int main(int argc, const char *argv[])
    {
    	int shmid,semid,s[]={0,1};
    	pid_t pid;
    	key_t key;
    	char *shmaddr;
    
    	if((key = ftok(".",'s')) == -1)//生成KEY值
    	{
    		perror("ftok");
    		exit(-1);
    	}
    
    	if((shmid = shmget(key,N,IPC_CREAT|0666)) < 0)//申请共享内存
    	{
    		perror("shmget");
    		exit(-1);
    	}
    
    	if((semid = semget(key,2,IPC_CREAT|0666)) < 0)//申请信号灯集
    	{
    		perror("semget");
    		goto _error1;//申请失败,释放申请的共享内存,程序退出
    	}
    
    	init_sem(semid,s,2);//信号灯集初始化
    
    	if((shmaddr = shmat(shmid,NULL,0)) == (char *)-1)//映射共享内存地址
    	{
    		perror("shmat");
    		goto _error2;//映射失败,释放申请的信号灯集,释放申请的共享内存,程序退出
    	}
    	
    	if((pid = fork()) < 0)//创建子进程
    	{
    		perror("fork");
    		goto _error2;
    	}
    	else if(pid == 0)
    	{
    		char *p,*q;
    		while(1)
    		{
    			sem_pv(semid,READ,-1);//对读信号灯进行P操作
    			p = q = shmaddr;
    			while(*q)
    			{
    				if(*q != ' ')
    				{
    					*p++ = *q;
    				}
    				q++;
    			}
    			*p = '\0';
    			printf("%s",shmaddr);
    			sem_pv(semid,WRITE,1);//对写信号灯进行V操作
    		}
    	}
    	else
    	{
    		while(1)
    		{
    			sem_pv(semid,WRITE,-1);//对写信号灯进行P操作
    			printf("input > ");
    			fgets(shmaddr,N,stdin);
    			if(strcmp(shmaddr,"quite\n") == 0)break;
    			sem_pv(semid,READ,1);//对读信号灯进行V操作
    		}
    		kill(pid,SIGUSR1);//给子进程发信号,让其结束
    	}
    
    
    _error2:
    	semctl(semid,0,IPC_RMID);//释放申请的信号灯集
    _error1:
    	shmctl(shmid,IPC_RMID,NULL);//释放申请的共享内存
    
    	return 0;
    }
    
    void init_sem(int semid,int s[],int n)//信号灯集初始化函数
    {
    	int i;
    	union semun myyun;
    	
    	for(i=0;i<n;i++)
    	{
    		myyun.val = s[i];//读信号灯值初始化为0,写信号灯值初始化为1
    		semctl(semid,i,SETVAL,myyun);
    	}
    }
    
    void sem_pv(int semid,int num,int op)//信号灯集P/V操作函数
    {
    	struct sembuf buf;
    
    	buf.sem_num = num;//信号灯编号
    	buf.sem_op = op;
    	buf.sem_flg = 0;
    	semop(semid,&buf,1);
    }
    
    
    展开全文
  • struct sembuf的部分讲解

    千次阅读 2017-09-07 16:52:40
    sembuf结构体的定义如下: [cpp] view plain copy     struct sembuf  {   unsigned short int sem_num; /* 信号量的序号从0~nsems-1 */   short int sem_op; /* ...

    sembuf结构体的定义如下:

    [cpp]  view plain  copy
     
     
    1. struct sembuf  
    2. {  
    3.   unsigned short int sem_num;   /* 信号量的序号从0~nsems-1 */  
    4.   short int sem_op;            /* 对信号量的操作,>0, 0, <0 */  
    5.   short int sem_flg;            /* 操作标识:0, IPC_WAIT, SEM_UNDO */  
    6. };  

    sem_num标识信号量集中的第几个信号量,0表示第1个,1表示第2个,nsems - 1表示最后一个。

    sem_op标识对信号量的所进行的操作类型。对信号量的操作有三种类型:

    • sem_op > 0,对该信号量执行挂出操作,挂出的值由sem_op决定,系统会把sem_op的值加到该信号量的当前值semval(参考文章开头关于每个信号量结构的定义)上。如果sem_flag指定了SEM_UNDO(还原)标志,那么相应信号量的semadj值会减掉sem_op的值。下面会说明semadj的含义。
    • sem_op < 0,对该信号量执行等待操作,当信号量的当前值semval >= -sem_op时,semval减掉sem_op的绝对值,为该线程分配对应数目的资源。如果指定SEM_UNDO,相应信号量的semadj就加上sem_op的绝对值。当semval < -sem_op时,相应信号量的semncnt就加1,调用线程被阻塞,直到semval >= -sem_op,当此条件满足时,调用线程被唤醒,执行相应的分配操作,然后semncnt减去1.
    • sem_op = 0,表示调用者希望semval变为0。如果为0则立即返回,如果不为0,相应信号量的semzcnt1,调用调用线程被阻塞。

    sem_flag:信号量操作的属性标志,如果为0,表示正常操作,如果为IPC_WAIT,使对信号量的操作时非阻塞的。即指定了该标志,调用线程在信号量的值不满足条件的情况下不会被阻塞,而是直接返回-1,并将errno设置为EAGAIN。如果为SEM_UNDO,那么将维护进程对信号量的调整值,以便进程结束时恢复信号量的状态。

    下面解释一下与单个信号量相关的几个值:

    semval:信号量的当前值,在文章开头信号量的结构中已提到。

    semncnt:等待semval变为大于当前值的线程数。在文章开头信号量的结构中已提到。

    semzcnt:等待semval变为0的线程数。在文章开头信号量的结构中已提到。

    semadj:指定信号量针对某个特定进程的调整值。只有sembuf结构的sem_flag指定为SEM_UNDO后,semadj才会随着sem_op而更新。讲简单一点:对某个进程,在指定SEM_UNDO后,对信号量semval值的修改都会反应到semadj上,当该进程终止的时候,内核会根据semadj的值,重新恢复信号量之前的值

    展开全文
  • 文章目录信号量概念通信原理相关APIsemget含义函数原型头文件函数参数函数返回值semctl含义函数原型头文件函数参数函数返回值semop含义函数原型头文件函数参数函数返回值sembuf结构体使用流程举例应用:对共享内存的...

    信号量概念

    •英文:semaphore,简称SEM,主要用来进程间同步
    •本质:内核维护的一个正整数,可对其进行各种操作+/-操作
    •分类:system V 信号量、POSIX 有名信号量、POSIX 无名信号量
    •用途:用来标识系统中可用的共享资源的个数,协调各进程有序地使用这些资源,防止发生冲突
    •信号量类似于酒店房间的房卡,房间资源是有限的、房卡也是有限的
    •P操作:程序在进入临界区之前要先对资源进行申请
    •V操作:程序离开临界区后要释放相应的资源,如房卡交给房东

    通信原理

    •类似于房卡,不是单个值,而是一组(实际上是数组)信号量元素构成
    •将信号量设置成一个绝对值
    •在信号量当前值的基础上加上一个数量
    •在信号量当前值的基础上减去一个数量,降到0以下可能会引起阻塞
    •阻塞进程一直等待其它进程修改信号量的值,直到恢复正常运行
    •信号量本身无意义,通常会与一块临界资源(如共享内存)关联使用

    相关API

    •获取信号量ID:int semget (key_t key, int nsems, int semflg);
    •P/V操作:int semop (int semid, struct sembuf *sops, size_t nsops);
    –操作术语:荷兰语中的首字母,由荷兰计算机科学家Edsger Dijkstra确定
    –其它操作术语:down(减小信号量)、up(增大信号量)
    –POSIX标准:wait、post
    •信号量设置:int semctl (int semid, int semnum, int cmd, …);

    semget

    含义

    创建或打开一个信号量

    函数原型

    int semget (key_t key, int nsems, int semflg);

    头文件

    sys/ipc.h
    sys/sem.h

    函数参数

    –key:用来表示信号量的键,通常使用值IPC_PRIVATE或由ftok创建
    –nsems:信号的数量,所有的信号放在一个数组内
    –semflg:位掩码,用来设置信号量的权限或检查一个已有信号量的权限
    >>IPC_CREAT:如果找不到指定key相关联的信号量,创建一个新信号量集合
    >>IPC_EXCL:若指定了IPC_CREAT且指定key关联的信号量存在,报EEXIST错误

    函数返回值

    –成功:返回用于操作信号量的句柄ID
    –失败:-1,并设置errno全局变量

    semctl

    含义

    信号量设置

    函数原型

    int semctl (int semid, int semnum, int cmd, …);

    头文件

    – #include <sys/ipc.h>
    – #include <sys/sem.h>

    函数参数

    –semid :用于操作信号量的句柄ID、标识符
    –semnum :信号的数量,所有的信号放在一个数组内
    –cmd:
    »IPC_RMID:删除信号量集及相关联的内核semid_ds数据结构
    »IPC_STAT:获取 semid_ds 副本
    »IPC_SET:设置 semid_ds 数据结构
    »GETVAL:获取信号集中第semnum个信号量的值
    »GETALL:获取所有的信号量的值
    »SETVAL:设置信号集中的第semnum个信号量的值

    函数返回值

    –成功:根据cmd命令,返回不同的值
    –失败:-1,并设置errno全局变量

    semop

    含义

    信号量P/V操作

    函数原型

    int semop(int semid, struct sembuf *sops, size_t nsops);

    头文件

    – #include <sys/ipc.h>
    – #include <sys/sem.h>

    函数参数

    –semid :用于操作信号量的IPC标识符
    –sops :指向数组的指针,数组中包含了需要执行的操作
    –nsops :数组的大小

    函数返回值

    –成功:根据cmd命令,返回不同的值
    –失败:-1,并设置errno全局变量

    sembuf结构体

    • sem_num:用来标识要操作的信号集中的信号量
    •sem_op:
    –若大于0:将sem_op的值加到信号量值上
    –若等于0:对信号量值进行检查,确定其当前值是否为0,若为0操作结束,若不为0,则一直阻塞,直到信号量的值变为0为止
    –若小于0:将信号量值减去sem_op。最后结果大于或等于0,操作立即结束;若最后结果小于0,则当前进程会阻塞
    •sem_flag:
    –SEM_UNDO
    –IPC_NOWAIT

    sem_flag:
    	–SEM_UNDO
    	–IPC_NOWAIT
    struct sembuf {
    	unsigned short sem_num; /* semaphore index in array */
    	short sem_op; /* semaphore operation */
    	short sem_flg; /* operation flags */
    };
    

    使用流程

    •使用semget创建或打开一个信号量集
    •使用semctl SETVAL或SETALL操作初始化集合中的信号量(其中一个进程操作即可,内核中维护,对其它进程是全局可见的)
    •使用semop操作信号量值。多个进程通过多信号量值的操作来表示一些临界资源的获取和释放
    •当所有进程不再需要信号量集时,使用semctl IPC_RMID操作删除这个信号量集(其中一个进程操作即可)

    举例

    创建一个信号量,并对其进行p/v操作

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    #include <sys/ipc.h>
    #include <sys/sem.h>
    #include <sys/types.h>
    
    #define handle_error(msg) \
        {perror(msg);exit(EXIT_FAILURE);}
    
    // creat a semphore
    // print and set semphore
    // P/V sem value
    // delete sem
    
    union semun
    {
    	int val;
    	struct semid_ds *buf;
    	unsigned short int *array;
    	struct seminfo *__buf;
    };
    
    /*
    struct sembuf
    {
    	unsigned short sem_num;//semaphore index in array
    	short sem_op;          //sepaphore operation
    	short sem_flg;         //operation flags
    };
    */
    
    int main (void)
    {
    	int sem_id;
    	key_t key;
    
    	if ((key = ftok(".", 514))== -1)
            handle_error("ftok");
    
    	if ((sem_id = semget (key, 3, IPC_CREAT | 0770)) == -1)
            handle_error("semget");
    	printf ("sem id: %d\n", sem_id);
    
    	// get sem value
    	int sem_value;
    	sem_value = semctl (sem_id, 0, GETVAL);
    	printf ("sem value: %d\n", sem_value);
    
    	// set sem value
    	union semun sem_union;
    	sem_union.val = 2;
    	semctl (sem_id, 0, SETVAL, sem_union);
    	sem_value = semctl (sem_id, 0, GETVAL);
    	printf ("sem value: %d\n", sem_value);
    
    
    	//sem p/v operations
    	struct sembuf sops;
    	sops.sem_num = 0;
    	sops.sem_op = -2;// if sem value=0, blocked
    	sops.sem_flg = SEM_UNDO;
    	if (semop (sem_id, &sops, 1) == -1)
            handle_error("sem_op");
    	sem_value = semctl (sem_id, 0, GETVAL);
    	printf ("sem value: %d\n", sem_value);
    	
    	sleep (30);
    	semctl (sem_id, 0, IPC_RMID);
    
    	return 0;
    }
    

    应用:对共享内存的同步访问

    write
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>
    #include <string.h>
    #include <strings.h>
    #include <sys/stat.h>
    #include <sys/ipc.h>
    #include <sys/sem.h>
    #include <sys/shm.h>
    
    union semun
    {
    	int val;
    	struct semid_ds *buf;
    	unsigned short int *array;
    	struct seminfo *__buf;
    };
    
    int sem_id;
    
    void sem_init (int semid, int nsignum, int sem_value)
    {
    	union semun sem_union;
    	sem_union.val = sem_value;
    	if (semctl (semid, nsignum, SETVAL, sem_union) == -1)
    	{
    		perror ("semctl");
    		exit (EXIT_FAILURE);
    	}
    }
     void sem_p (int semid, int nsignum)
    {
    	struct sembuf sops;
    	sops.sem_num = nsignum;
    	sops.sem_op  = -1;
    	sops.sem_flg = SEM_UNDO;
    	if (semop (sem_id, &sops, 1) == -1)
    	{
    		perror ("semop");
    		exit (EXIT_FAILURE);
    	}
    }
     void sem_v (int semid, int nsignum)
    {
    	struct sembuf sops;
    	sops.sem_num = nsignum;
    	sops.sem_op  = 1;
    	sops.sem_flg = SEM_UNDO;
    	if (semop (sem_id, &sops, 1) == -1)
    	{
    		perror ("semop");
    		exit (EXIT_FAILURE);
    	}
    }
    
    void sem_print (int sem_id, int nsignum)
    {
    	int sem_value;
    	sem_value = semctl (sem_id, nsignum, GETVAL);
    	printf ("sem[%d] = %d\n", nsignum, sem_value);
    }
    int main (void)
    {
    	int shm_id;
    	key_t shm_key = ftok ("./", 5151);
    	key_t sem_key = ftok ("./", 5152);
    
    	shm_id = shmget (shm_key, 1028, IPC_CREAT | 0644);
    	char *shm_addr = shmat (shm_id, NULL, 0);
    
    	sem_id = semget (sem_key, 2, IPC_CREAT | 0644);
    	if (sem_id == -1)
    	{
    		sem_id = semget (sem_key, 2, 0644);
    	}
    	else
    	{
    		sem_init (sem_id, 0, 0); //sem[0]: for read
    		sem_init (sem_id, 1, 1); //sem[1]: for write
    	}
    	while (1)           //write
    	{
    		sem_p (sem_id, 1);
    		fgets (shm_addr, 1028, stdin);
    		sem_v (sem_id, 0);
    	}
    	return 0;
    }
    
    
    read
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>
    #include <string.h>
    #include <strings.h>
    #include <sys/stat.h>
    #include <sys/ipc.h>
    #include <sys/sem.h>
    #include <sys/shm.h>
    #include <sys/types.h>
    
    union semun
    {
    	int val;
    	struct semid_ds *buf;
    	unsigned short int *array;
    	struct seminfo *__buf;
    };
    
    int sem_id;
    
    void sem_init (int semid, int nsignum, int sem_value)
    {
    	union semun sem_union;
    	sem_union.val = sem_value;
    	if (semctl (semid, nsignum, SETVAL, sem_union) == -1)
    	{
    		perror ("semctl");
    		exit (EXIT_FAILURE);
    	}
    }
     void sem_p (int semid, int nsignum)
    {
    	struct sembuf sops;
    	sops.sem_num = nsignum;
    	sops.sem_op  = -1;
    	sops.sem_flg = SEM_UNDO;
    	if (semop (sem_id, &sops, 1) == -1)
    	{
    		perror ("semop");
    		exit (EXIT_FAILURE);
    	}
    }
     void sem_v (int semid, int nsignum)
    {
    	struct sembuf sops;
    	sops.sem_num = nsignum;
    	sops.sem_op  = 1;
    	sops.sem_flg = SEM_UNDO;
    	if (semop (sem_id, &sops, 1) == -1)
    	{
    		perror ("semop");
    		exit (EXIT_FAILURE);
    	}
    }
    
    void sem_print (int sem_id, int nsignum)
    {
    	int sem_value;
    	sem_value = semctl (sem_id, nsignum, GETVAL);
    	printf ("sem[%d] = %d\n", nsignum, sem_value);
    }
    int main (void)
    {
    	int shm_id;
    	key_t shm_key = ftok ("./", 5151);
    	key_t sem_key = ftok ("./", 5152);
    
    	shm_id = shmget (shm_key, 1028, IPC_CREAT | 0644);
    	char *shm_addr = shmat (shm_id, NULL, 0);
    
    	sem_id = semget (sem_key, 2, IPC_CREAT | 0644);
    	if (sem_id == -1 )
    	{
    		perror ("semget");
    		exit (EXIT_FAILURE);
    	}
    	else
    	{
    		sem_init (sem_id, 0, 0);//sem[0]: for read
    		sem_init (sem_id, 1, 1);//sem[1]: for write
    	}
    	while (1)            //read
    	{
    		sem_p (sem_id, 0);
    		printf ("from shm:%s", shm_addr);
    		sem_v (sem_id, 1);
    	}
    	return 0;
    }
    
    
    展开全文
  • PV操作 文档

    2012-11-15 13:50:30
    semop 的第二个参数 sops 指向的结构体数组中,每个 sembuf 结构体对应一个特定信号的操作。因此对信号量进行操作必须熟悉该数据结构,该结构定义在 linux/sem.h,如下所示: struct sembuf{ unsigned short sem_...
  • 结构体还定义了几个函数指针,这几个函数类似于各个锁需要实现的接口,值得注意的是 lock_rd 和 trylock_rd两个函数是专门为了 swFileLock 和 swRWLock 设计的,其他锁没有这两个函数。 typedef struct _swLock { ...
  • 信号灯操作semop和sembuf结构

    千次阅读 2009-02-04 16:15:00
    semop操作中:sembuf结构的sem_flg成员可以为0、IPC_NOWAIT、SEM_UNDO 。为SEM_UNDO时,它将使操作系统跟踪当前进程对这个信号量的修改情况,如果这个进程在没有释放该信号量的情况下终止,操作系统将自动释放该...
  • Linux内核中,每个消息队列都维护一个结构体,此结构体保存着消息队列当前状态信息,该结构体在头文件linux/msg.h中定义。 3、ipc_perm内核数据结构 struct ipc_perm{ key_t key; uid_t uid; gid_t gid; .......}; ...
  • 头文件包含结构体struct sembuf 定义为全局变量时,make报错 [neo@localhost tmp]$ cat t1.c #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem....
  • int semop(int semid, struct sembuf *sops, unsigned nsops); semid标识其操作的信号量集。 其中sops指向一个如下结构的数组: struct sembuf{ unsigned short sem_num; /* semaphore number: 0, 1, …., nsems-1 ...
  • int semop(int semid, struct sembuf *sops, unsigned nsops); //参数一:信号量集的id //参数二:一个结构体数组的首地址 //参数三:结构体数组的大小 //这个结构体如下: struct sembuf { unsigned short sem_...
  • Linux IPC实践(11) --System V信号量(1)

    千次阅读 2015-02-19 15:52:53
    信号量API#include #include #include int semget(key_t key, int nsems, int semflg); int semctl(int semid, int semnum, int cmd, ......int semop(int semid, struct sembuf *sops, unsigned nsops);semgetint s
  • 信号量

    万次阅读 多人点赞 2017-03-10 20:44:41
    注意这里的结构体sembuf struct sembuf { unsigned short sem_num;操作信号在信号集中的编号,第一个信号的编号为0,第二个为1,一次后推 short sem_op;信号资源,如果有就分配,...
  • 每个IPC都会维护一个结构体(ipc_perm): 一. 管道通信(pipe) 管道,通常指无名管道,是 UNIX 系统IPC最古老的形式。 1、特点: 它是半双工的(即数据只能在一个方向上流动),具有固定的读端和写端。 它只能...
  • 成功:0 错误:-1 其中struct sembuf结构体描述如下: sem_num:除非使用一组信号量,否则它为0; sem_op:操作时需要改变的数据,-1为P等待,+1为V发送信号; sem_flag:通常为SEM_UNDO,使操作系统跟踪信号,在...
  • 参数: semid: 信号量集ID sops:sembuf 结构体数组指针 nsops:sops中信号量的个数,sizeof(sops)/sizeof(sops[0]) sem_num: 信号量集中信号量的编号 sep_op: 正数为V 操作(对信号量加操作),负数为P操作(对信号...
  • Linux 多进程通信开发(六): 共享内存

    千次阅读 2019-04-10 19:11:37
    buf 当 cmd 取值为 IPC_SET 时,将 buf 中的内容设置到共享内存的 shmid_ds 结构体中 cmd 取值 IPC_RMID 目的是删除内核中的共享内存 cmd 取值 IPC_SET 是为了设置共享内存的 shmid_ds 结构体 cmd 取值 IPC_...
  • 【Linux系统编程】System V信号量

    千次阅读 2019-11-08 11:49:14
    nsops:操作信号量的结构体数组中元素的个数。 返回值: 成功: 0 失败: - 1 04. 程序示例 4.1 创建和删除信号量数组 # include # include # include # include # include ...
  • sops 是一个 sembuf 类型结构体,详细定义如下: struct sembuf { unsigned short int sem_num; /* semaphore number */ short int sem_op; /* semaphore operation */ short int sem_flg; /* operation ...
  • 进程间通信-system-v

    2019-05-03 18:45:05
    结构体mymesg用户可自定义,但第一个成员必须是mytype 接收消息 # include ssize_t msgrcv ( int msgqid , void * ptr , size_t nbytes , long type , int flag ) ; 返回:成功返回消息的数据...
  • Linux -- system V IPC

    2019-04-03 11:29:22
    int semop(int semid, struct sembuf semoparray[], size_t nops); //信号量P/V操作,nops表示数组的长度 semget system v信号量在每次申请使用时都不是单个的,而是一个集合,所以semget中才需要指定对应的集合...
  • 管道是基于文件系统实现的,信号是内核专门实现信号的task_struct结构体来实现的,套接字通信是基于网络通信来实现的。 按照功能分类: 共享内存, 消息队列,管道和套接字通信是可以传输比较大的数据的,信号量是...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,776
精华内容 710
关键字:

sembuf结构体