`
T240178168
  • 浏览: 361375 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

linux进程通信-信号量使用

阅读更多
一、相关知识

信号量:一个整数;
  大于或等于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, //指向元素操作数组
  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 服务器

#i nclude <sys/sem.h>
#i nclude <sys/ipc.h>

#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 <= 3;i++){
  sleep(1);
  p(semid);
  sleep(READTIME);
  msg[5] = '0' + i;
  memcpy(shm,msg,sizeof(msg));
  sleep(58);
  v(semid);
}
shmdt(shm);
shmctl(shmid,IPC_RMID,&buf);
del_sem(semid);
return 0;
//gcc -o shm shm.c -g
}

2.2 客户端

#i nclude <sys/sem.h>
#i nclude <time.h>
#i nclude <sys/ipc.h>

#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 < 3;i ++){
  sleep(2);
  wait_v(semid);
  printf("Message geted is: %s \n",shm + 1);
  out_time();
}
shmdt(shm);
return 0;
// gcc -o shmc shmC.c -g
}
分享到:
评论

相关推荐

    Linux进程间通信-信号量通信进程互斥实例.pdf

    Linux进程间通信-信号量通信进程互斥实例.pdf 学习资料 复习资料 教学资源

    Linux多进程通信-信号量,共享内存示例

    本示例的代码中主要采用了信号量和共享内存来实现linux下多进程之间的通信。

    Linux进程间通信-信号量通信进程同步实例.pdf

    Linux进程间通信-信号量通信进程同步实例.pdf 学习资料 复习资料 教学资源

    非常宝贵的LINUX学习笔记

    【linux学习笔记-1】使用GDB调试简单的用户程序 【linux学习笔记-2】父子进程共享文件描述符 【linux学习笔记-3】文件操作...【linux学习笔记--18】POSIX IPC——信号量 【linux学习笔记--19】POSIX IPC——共享内存

    Linux学习笔记Linux学习资料Linux教程

    【linux学习笔记--18】POSIX IPC——信号量.doc 【linux学习笔记--19】POSIX IPC——共享内存.doc 【linux学习笔记-10】Linux进程相关系统调用(三).doc 【linux学习笔记-11】守护进程daemon.doc 【linux学习笔记-...

    使用共享内存及信号量实现进程间通信例子

    代码实现了共享内存和信号量的结合,实现进程间通信及其同步问题。通过此代码可以理解共享内存及信号量基本函数的使用及实现原理。

    linux进程通信

    本文描述的是在linux系统下的进程分析,针对linux的进程间的通信--信号量为重点展开

    进程同步——信号量机制

    关于信号量的文章,生产者消费者问题与读者写者问题---信号量机制,PV操作——进程同步的信号量问题,利用信号机制实现的 父子进程同步,嵌入式linux的学习笔记-进程间通信的信号与信号集(四)1)进程的同步与互斥 ...

    Linux-进程间通信

    ****Linux****-进程间通信-每块都是概括 管道-消息队列-信号量-共享内存-套接字-信号

    linux 网络编程 进程通信 信号量

    一些关于Linux的网络编程方面的资料,对于初学者有很大的帮助.

    Linux进程间通信的例子

    资源中包含了Linux进程间通信的例子,同时有源文件和可执行文件。 源码主要包含了Linux下IPC机制的本地进程通信方式,包含了IPC共享内存,IPC信号量,IPC消息队列的实现,以及Linux下判断进程退出原因的示例程序。

    Linux 下进程间通信实例

    Linux 下进程间通信实例之一——共享内存 使用了信号量用于进程间的同步

    进程的产生与子进程----MUTEX信号量,PV操作

    LINUX下的进程问题,实现进程的创建,子进程与父进程通信…………………………P,V操作

    LInux进程通信

    使用信号量和共享内存实现,在linux下实现进程同步,通信

    Linux进程间通信.pdf

    linux 进程间通信相关教程,管道 共享内存 共享队列 信号量 socket 锁 方面的讲解,值得下载

    详解Linux进程间通信——使用信号量

    主要介绍了详解Linux进程间通信——使用信号量,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    linux进程间通信消息队列信号量共享内存等.pptx

    linux进程间通信消息队列信号量共享内存等.pptx

    Linux 进程通信

    首先,进程间通信至少可以通过传送打开文件来实现,不同的进程...而Linux作为一种新兴的操作系统,几乎支持所有的Unix下常用的进程间通信 方法:管道、消息队列、共享内存、信号量、套接口等等。下面我们将逐一介绍。

    Linux进程通信代码

    LinuxIPC通信代码,包含有匿名管道,命名管道,消息队列,信号量,信号,共享内存

    linux进程间通信 教程

    IPC(InterProcess Communication)是各种进程通信方式的统称,主要有下面几种类型:  管道  FIFO(命名管道)  消息队列  信号量  共享空间  套接口 前五种IPC只能用于一台主机内的进程间通信,套接口...

Global site tag (gtag.js) - Google Analytics