`
T240178168
  • 浏览: 369111 次
  • 性别: 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多进程通信-信号量,共享内存示例

    在Linux操作系统中,多进程通信(IPC,Inter-Process Communication)是实现不同进程间数据交换的关键技术。本示例通过信号量和共享内存这两种IPC机制,展示了如何在多个进程中有效地协同工作。信号量用于同步对共享...

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

    本实例通过信号量实现了Linux进程间的互斥通信,展示了如何利用信号量控制并发进程对共享资源的访问。这种机制对于多线程或多进程环境中的资源管理至关重要,可以有效地防止数据竞争,确保程序的正确性。同时,这个...

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

    本文将深入探讨Linux系统中的一个特定IPC机制——信号量(Semaphore)及其在进程同步中的应用。信号量是一种用于控制多个进程对共享资源访问的同步工具,它能有效地防止竞态条件和死锁的发生。 信号量是一个整数值...

    Linux进程间通信-信号通信信号发送实例.pdf

    总结来说,信号通信是Linux IPC的重要组成部分,它提供了简单而快速的进程间通信方式。通过`kill`、`raise`和`sigqueue`等函数,程序员可以灵活地控制和传递信息,实现进程间的交互。然而,由于信号携带信息有限,...

    01--Linux系统编程-信号.docx

    Linux系统编程中的信号机制是操作系统提供的一种异步通信方式,它允许进程间或者操作系统与进程之间传递简短的通知。信号的概念源于现实生活中的一些信号行为,它们具有意图简单、信息量小且满足特定触发条件的特点...

    Linux进程间通信-信号通信定时信号实例.pdf

    信号是Linux系统中进程间通信的一种轻量级方式,它能够用来中断进程的执行、改变进程状态或者通知进程发生了某些系统事件。在示例程序中,使用了`&lt;signal.h&gt;`头文件,这是处理信号的必备库。 定时信号通常与`alarm...

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

    信号是Linux系统中用于进程间通信的一种轻量级机制,它允许一个进程向另一个进程发送一个消息,告知接收进程发生了某种事件或需要执行某个动作。信号通信具有快速、简单的特点,但同时也存在信息量有限和同步能力较...

    linux系统编程--进程间通信--管道

    常用的进程间通信方式有多种,包括无名管道、有名管道、信号、System V IPC 对象共享内存、消息队列和信号灯、BSD 套接字等。 本文主要介绍无名管道(pipe)的概念和使用方法。无名管道是一种半双工的通信方式,...

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

    本文将深入探讨Linux网络编程的关键概念、进程通信以及信号量的应用。 一、Linux网络编程基础 1. **套接字(Sockets)**:套接字是网络通信的基本接口,它允许应用程序在不同或同一机器上的进程间交换数据。在...

    非常宝贵的LINUX学习笔记

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

    linux-fusion-1.1.tar.gz_fusion_linux fusion_linux 进程 通信_linux-fu

    描述中提到“linux进程间高级通信的一个模块”,这暗示了Linux Fusion可能是一个专注于进程间通信(IPC,Inter-Process Communication)的库或框架。在Linux系统中,进程间通信是不同进程之间交换数据的重要机制,...

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

    本示例代码着重于使用共享内存和信号量来解决进程间的通信和同步问题,这是一种高效且灵活的方法,特别是在多处理器和多线程环境中。下面我们将详细探讨这些概念以及它们在Linux系统中的实现。 **共享内存** 是一种...

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

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

    linux进程间通信--IPC

    ### Linux进程间通信(IPC) 进程间通信(InterProcess Communication,简称IPC)是操作系统中一个重要的概念,指在计算机系统中不同的进程之间进行数据交换或通信的方法。在Linux环境下,进程间通信支持多种机制,...

    嵌入式Linux高级编程--04posix_进程间通信.ppt

    目前Linux使用的进程间通信方式包括管道、消息队列、共享内存、信号量和信号等。 管道通信是进程间通信的一种方式,管道是单向的、先进先出的、无结构的、固定大小的字节流。写进程在管道的尾端写入数据,读进程在...

    进程通信之信号量.zip

    本文将深入探讨“进程通信之信号量”的概念,特别是在Linux环境下的实现。我们将通过分析名为"seml.c"的源代码来理解这一关键机制。 信号量(Semaphore)是一种同步原语,它在多进程环境下用于控制对共享资源的访问...

    linux进程间通信与同步.pdf

    ### Linux进程间通信与同步详解 #### 一、概述 在多任务操作系统中,进程间通信与同步机制是解决进程间数据交换与资源共享的关键技术。这些机制确保了多个并发运行的任务能够有效地协作,并且避免了资源冲突。对于...

    UNIX Linux实验教程 4实验四Linux进程间通信.doc

    此外,UNIX/Linux 操作系统还提供了共享内存、信号量、套接口和全双工管道等其他进程间通信机制。共享内存是指多个进程可以访问同一个内存区域,信号量是指一种特殊的变量,用于多个进程之间的同步和通信。套接口是...

Global site tag (gtag.js) - Google Analytics