免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 824 | 回复: 0
打印 上一主题 下一主题

linux进程通信-信号量使用 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-01-05 16:48 |只看该作者 |倒序浏览

一、相关知识
信号量:一个整数;
  大于或等于0时代表可供并发进程使用的资源实体数;
  小于0时代表正在等待使用临界区的进程数;
  用于互斥的信号量初始值应大于0;
  只能通过P、V原语操作而改变;
信号量元素组成:
  1、表示信号量元素的值;
  2、最后操作信号量元素的进程ID
  3、等待信号量元素值+1的进程数;
  4、等待信号量元素值为0的进程数;

二、主要函数

1.1 创建信号量
int semget(
  key_t key,  //标识信号量的关键字,有三种方法:1、使用IPC——PRIVATE让系统产生,
     // 2、挑选一个随机数,3、使用ftok从文件路径名中产生
  int nSemes,  //信号量集中元素个数
  int flag  //IPC_CREAT;IPC_EXCL 只有在信号量集不存在时创建
)
成功:返回信号量句柄
失败:返回-1

1.2 使用ftok函数根据文件路径名产生一个关键字
key_t ftok(const char *pathname,int proj_id);
路径名称必须有相应权限

1.3 控制信号量
int semctl(
  int semid,  //信号量集的句柄
  int semnum,  //信号量集的元素数
  int cmd,  //命令
  /*union senum arg */... //  
)
成功:返回相应的值
失败:返回-1

命令详细说明:
cmd:   IPC_RMID 删除一个信号量
  IPC_EXCL 只有在信号量集不存在时创建
  IPC_SET 设置信号量的许可权
  SETVAL 设置指定信号量的元素的值为 agc.val
  GETVAL 获得一个指定信号量的值
  GETPID 获得最后操纵此元素的最后进程ID
  GETNCNT 获得等待元素变为1的进程数
  GETZCNT 获得等待元素变为0的进程数
  
union senum 定义如下:
union senum{
  int val;
  struct semid_ds *buf;
  unsigned short * array;
}agc;
其中 semid_ds 定义如下:
struct semid_ds{
  struct ipc_pem sem_pem;  //operation pemission struct
  time_t sem_otime;  //last semop()time
  time_t sem_ctime;  //last time changed by semctl()
  struct sem *sembase;  //ptr to first semaphore in array
  struct sem_queue *sem_pending; //pending operations
  struct sem_queue *sem_pending_last; //last pending operations
  struct sem_undo *undo;  //undo requests on this arrary
  unsigned short int sem_nsems; //number of semaphores in set
};
  
1.4 对信号量 +1 或 -1 或测试是否为0
int semop(
  int semid,
  struct sembuf *sops, //指向元素僮魇??BR>  unsigned short nsops //数组中元素操作的个数
)

结构 sembuf 定义
sembuf{
  short int sem_num; //semaphore number
  short int sem_op; //semaphore operaion
  short int sem_flg //operation flag
};

三、例子:
2.1 服务器
#include
#include
#define SEGSIZE 1024
#define READTIME 1
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
} arg;
//生成信号量
int sem_creat(key_t key)
{
union semun sem;
int semid;
sem.val = 0;
semid = semget(key,1,IPC_CREAT|0666);
if (-1 == semid){
  printf("create semaphore error\n");
  exit(-1);
}
semctl(semid,0,SETVAL,sem);
return semid;
}
//删除信号量
void del_sem(int semid)
{
union semun sem;
sem.val = 0;
semctl(semid,0,IPC_RMID,sem);
}
//p
int p(int semid)
{
struct sembuf sops={0,+1,IPC_NOWAIT};
return (semop(semid,&sops,1));
}
//v
int v(int semid)
{
struct sembuf sops={0,-1,IPC_NOWAIT};
return (semop(semid,&sops,1));
}
int main()
{
key_t key;
int shmid,semid;
char *shm;
char msg[7] = "-data-";
char i;
struct semid_ds buf;

key = ftok("/",0);
shmid = shmget(key,SEGSIZE,IPC_CREAT|0604);
if (-1 == shmid){
  printf(" create shared memory error\n");
  return -1;
}
shm = (char *)shmat(shmid,0,0);
if (-1 == (int)shm){
  printf(" attach shared memory error\n");
  return -1;
}
semid = sem_creat(key);
for (i = 0;i
#include
#include
#define SEGSIZE 1024
#define READTIME 1
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
} arg;
// 打印程序执行时间
void out_time(void)
{
static long start = 0;
time_t tm;
if (0 == start){
  tm = time(NULL);
  start = (long)tm;
  printf(" now start ...\n");
}
printf(" second: %ld \n",(long)(time(NULL)) - start);
}
//创建信号量
int new_sem(key_t key)
{
union semun sem;
int semid;
sem.val = 0;
semid = semget(key,0,0);
if (-1 ==  semid){
  printf("create semaphore error\n");
  exit(-1);
}
return semid;
}
//等待信号量变成0
void wait_v(int semid)
{
struct sembuf sops={0,0,0};
semop(semid,&sops,1);
}
int main(void)
{
key_t key;
int shmid,semid;
char *shm;
char msg[100];
char i;

key = ftok("/",0);
shmid = shmget(key,SEGSIZE,0);

if(-1 == shmid){
  printf(" create shared memory error\n");
  return -1;
}
shm = (char *)shmat(shmid,0,0);
if (-1 == (int)shm){
  printf(" attach shared memory error\n");
  return -1;
}
semid = new_sem(key);
for (i = 0;i

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/29346/showart_226918.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP