Linux下C语言实现显示SYSTEM V信号量信息的小工具

来源:互联网 发布:麒麟与ubuntu的区别 编辑:程序博客网 时间:2024/05/22 03:19

1、源代码

/*************************************************************************  > File Name: svsem_myls.c  > Author:zhangshengshan  > Mail: zsszsszsszss@126.com   > show all the semophmore ************************************************************************/#include<stdio.h>#include<sys/types.h>#include<stdlib.h>#include<sys/sem.h>#include "semun.h"#include <sys/ipc.h>int get_sem_index(int *pIndex,union semun *pSemun){*pIndex = semctl(0,0,SEM_INFO,*pSemun);if (-1==*pIndex){return -1;}return *pIndex;}int main(int argc,char * argv[]){union semun union_sem;union semun arg;union semun dummy;struct semid_ds ds_sem;struct seminfo info_sem;int index=-1;int id_sem=0;int num_sem=0;int i=-1;int j=-1;int k=-1;union_sem.__buf=&info_sem;//arg.buf=&ds_sem;//从内核获取信号量的索引  if( -1==get_sem_index(&index,&union_sem)){printf("get index failure!\n");exit(1);}//show_semid();printf("semid  num  sem# value SEMPID SEMNCNT SEMZCNT\n");for (i=0;i<=index;i++){arg.buf=&ds_sem;//获取信号集描述符id_sem=semctl(i,0,SEM_STAT,arg);k=arg.buf->sem_nsems;//show  every sem info in id_sem//member array is a pointor!arg.array=calloc(arg.buf->sem_nsems,sizeof(arg.array[0]));if (arg.array == NULL){printf("calloc error!\n");exit (9);}// here the param will be changed! because it is a union!if (semctl(id_sem,0,GETALL,arg)==-1){printf("semctl-getALL\n");exit(8);}printf("now arg.buf->sem_nsems is %d, and ds_sem.sem_nsems is %d\n",arg.buf->sem_nsems,ds_sem.sem_nsems);//printf("sem # value  SEMPID SEMNCNT SEMZCNT\n");for(j=0;/**/ j<k;j++){printf("%5d %5d %3d %5d %5d %5d %5d\n",id_sem,k,j,arg.array[j],\semctl(id_sem,j,GETPID,dummy),\semctl(id_sem,j,GETNCNT,dummy),\semctl(id_sem,j,GETZCNT,dummy));}}return 0;}

2、程序运行结果

编译上述程序并且运行可以得到结果为:


这里,semid列表示信号集标识符号、每一个信号集合中可能有多个信号量。这里显示的图形表示163840信号集合现在有两个信号量,而信号集合196609中包含三个信号量。

3、相关数据结构


3.1 union semun结构

 
在进行信号量相关编程的时候经常需要提供union semun共用体,该公用体需要用户自行实现。这里的semid_ds是描述信号量集合的结构体。

3.2 struct semid_ds结构体

该结构体描述了信号量集合的相关信息,其中sem_perm成员描述了该信号量集合的属性和权限,而sem_nsems成员则表示该信号量集合中具有多少成员。

4、semct()函数及相关标志

semctl函数提供了对信号量集合以及信号量的种种操作,上图的DESCRIPTION中清楚的描述了semtcl所需要的各个函数的含义。我们在程序中使用了
*pIndex = semctl(0,0,SEM_INFO,*pSemun);
SEM_INFO标志同IPC_INFO 标志基本相同,在帮助手册中其描述如下:
可见其主要功能是返回seminfo的结构体,描述相关额信息,seminfo结构体可以在Linux下man semctl 查看。
那么这里的semctl返回的数值是什么含义呢?
可见在 使用了SEM_INFO的情况下,得到的返回值是 the index of the highest used entry in the kernel's internal array recording information about all semaphore sets(得到的是内核中记录所有信号量集合中最大的那个记录),关键是后面的的这句话比较关键,给出了如何获取信号量集合描述符号的方法,this information can be used with repeated SEM_STAT operations to obtain information about all semaphore sets on the system.
这里请注意在使用SEM_STAT获取相关信号量集合semctl函数的第一个参数semid不是通常意义下的信号量集合的标识符号(即不是通过semget()获取到的标识符号!),而是使用SEM_INFO标志semctl()获得的内核的符号。

5、程序整体思路

1、利用semctl()和SEM_INFO从内核获取系统中的信号量共有多少个?

*pIndex = semctl(0,0,SEM_INFO,*pSemun);

2、循环利用semctl()和SEM_STAT获取信号量集合的描述符号(这个描述符号对应semget()获取的信号集合的描述符号)

id_sem=semctl(i,0,SEM_STAT,arg);

3、循环利用semctl()和GETALL获取每个信号集合中的所有信号量的信息,并且打印相关信息。

if (semctl(id_sem,0,GETALL,arg)==-1)



0 0
原创粉丝点击