dedecms织梦内容管理系统    
首页 | java | C/C++ | PHP | 操作系统 | ajax | 脚本编程 | 安全技术 | 本站下载页 | flex | CRM | 专题 | QQ群 | 测试中心 | 会员中心 | 积分规则
  当前位置:主页>操作系统>linux>文章内容
Linux下的C编程实战之三(下)
来源:天极网软件频道 作者:宋宝华
3.进程间通信

  Linux的进程间通信(IPC,InterProcess Communication)通信方法有管道、消息队列、共享内存、信号量、套接口等。

  管道分为有名管道和无名管道,无名管道只能用于亲属进程之间的通信,而有名管道则可用于无亲属关系的进程之间。

#define INPUT 0
#define OUTPUT 1
void main()
{
 int file_descriptors[2];
 /*定义子进程号 */
 pid_t pid;
 char buf[BUFFER_LEN];
 int returned_count;
 /*创建无名管道*/
 pipe(file_descriptors);
 /*创建子进程*/
 if ((pid = fork()) == - 1)
 {
  printf("Error in fork\n");
  exit(1);
 }
 /*执行子进程*/
 if (pid == 0)
 {
  printf("in the spawned (child) process...\n");
  /*子进程向父进程写数据,关闭管道的读端*/
  close(file_descriptors[INPUT]);
  write(file_descriptors[OUTPUT], "test data", strlen("test data"));
  exit(0);
 }
 else
 {
  /*执行父进程*/
  printf("in the spawning (parent) process...\n");
  /*父进程从管道读取子进程写的数据,关闭管道的写端*/
  close(file_descriptors[OUTPUT]);
  returned_count = read(file_descriptors[INPUT], buf, sizeof(buf));
  printf("%d bytes of data received from spawned process: %s\n",
  returned_count, buf);
 }
}

  上述程序中,无名管道以

int pipe(int filedis[2]);

  方式定义,参数filedis返回两个文件描述符filedes[0]为读而打开,filedes[1]为写而打开,filedes[1]的输出是filedes[0]的输入;

  在Linux系统下,有名管道可由两种方式创建(假设创建一个名为“fifoexample”的有名管道):

  (1)mkfifo("fifoexample","rw");

  (2)mknod fifoexample p

  mkfifo是一个函数,mknod是一个系统调用,即我们可以在shell下输出上述命令。

  有名管道创建后,我们可以像读写文件一样读写之:

/* 进程一:读有名管道*/
void main()
{
 FILE *in_file;
 int count = 1;
 char buf[BUFFER_LEN];
 in_file = fopen("pipeexample", "r");
 if (in_file == NULL)
 {
  printf("Error in fdopen.\n");
  exit(1);
 }
 while ((count = fread(buf, 1, BUFFER_LEN, in_file)) > 0)
  printf("received from pipe: %s\n", buf);
  fclose(in_file);
}

/* 进程二:写有名管道*/
void main()
{
 FILE *out_file;
 int count = 1;
 char buf[BUFFER_LEN];
 out_file = fopen("pipeexample", "w");
 if (out_file == NULL)
 {
  printf("Error opening pipe.");
  exit(1);
 }
 sprintf(buf, "this is test data for the named pipe example\n");
 fwrite(buf, 1, BUFFER_LEN, out_file);
 fclose(out_file);
}

  消息队列用于运行于同一台机器上的进程间通信,与管道相似;

  共享内存通常由一个进程创建,其余进程对这块内存区进行读写。得到共享内存有两种方式:映射/dev/mem设备和内存映像文件。前一种方式不给系统带来额外的开销,但在现实中并不常用,因为它控制存取的是实际的物理内存;常用的方式是通过shmXXX函数族来实现共享内存:

int shmget(key_t key, int size, int flag); /* 获得一个共享存储标识符 */

  该函数使得系统分配size大小的内存用作共享内存;

void *shmat(int shmid, void *addr, int flag); /* 将共享内存连接到自身地址空间中*/

  shmid为shmget函数返回的共享存储标识符,addr和flag参数决定了以什么方式来确定连接的地址,函数的返回值即是该进程数据段所连接的实际地址。此后,进程可以对此地址进行读写操作访问共享内存。

  本质上,信号量是一个计数器,它用来记录对某个资源(如共享内存)的存取状况。一般说来,为了获得共享资源,进程需要执行下列操作:

  (1)测试控制该资源的信号量;

  (2)若此信号量的值为正,则允许进行使用该资源,进程将进号量减1;

  (3)若此信号量为0,则该资源目前不可用,进程进入睡眠状态,直至信号量值大于0,进程被唤醒,转入步骤(1);

  (4)当进程不再使用一个信号量控制的资源时,信号量值加1,如果此时有进程正在睡眠等待此信号量,则唤醒此进程。

  下面是一个使用信号量的例子,该程序创建一个特定的IPC结构的关键字和一个信号量,建立此信号量的索引,修改索引指向的信号量的值,最后清除信号量:

#include <stdio.h>
#include <sys/types.h>
#include <sys/sem.h>
#include <sys/ipc.h>
void main()
{
 key_t unique_key; /* 定义一个IPC关键字*/
 int id;
 struct sembuf lock_it;
 union semun options;
 int i;

 unique_key = ftok(".", 'a'); /* 生成关键字,字符'a'是一个随机种子*/
 /* 创建一个新的信号量集合*/
 id = semget(unique_key, 1, IPC_CREAT | IPC_EXCL | 0666);
 printf("semaphore id=%d\n", id);
 options.val = 1; /*设置变量值*/
 semctl(id, 0, SETVAL, options); /*设置索引0的信号量*/

 /*打印出信号量的值*/
 i = semctl(id, 0, GETVAL, 0);
 printf("value of semaphore at index 0 is %d\n", i);

 /*下面重新设置信号量*/
 lock_it.sem_num = 0; /*设置哪个信号量*/
 lock_it.sem_op = - 1; /*定义操作*/
 lock_it.sem_flg = IPC_NOWAIT; /*操作方式*/
 if (semop(id, &lock_it, 1) == - 1)
 {
  printf("can not lock semaphore.\n");
  exit(1);
 }

 i = semctl(id, 0, GETVAL, 0);
 printf("value of semaphore at index 0 is %d\n", i);

 /*清除信号量*/
 semctl(id, 0, IPC_RMID, 0);
}

  套接字通信并不为Linux所专有,在所有提供了TCP/IP协议栈的操作系统中几乎都提供了socket,而所有这样操作系统,对套接字的编程方法几乎是完全一样的。

  4.小节

  本章讲述了Linux进程的概念,并以多个实例讲解了进程控制及进程间通信方法,理解这一章的内容可以说是理解Linux这个操作系统的关键。

上一篇:Linux下的C编程实战之三(上)   下一篇:Linux下的C编程实战之四(上)
[收藏] [推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
用户名: 新注册) 密码: 匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论
  热点文章
·Linux常用基本命令及应用技巧
·写得蛮好的linux学习笔记
·学会在Linux下对硬盘分区
·找回Redhat的超级用户密码
·Linux下C语言编程
·GDB教程
·Cron服务配置详解
·Linux与Unix二大操作系统编程的
·Linux 2.6 内核的嵌入式系统应用
·Linux和Windows系统调用的比较
·vim命令(一)
·vim 命令(二)
  相关文章
·Linux下的C编程实战之三(上)
·Linux下的C编程实战之四(上)
·Linux下的C编程实战之文件系统编
·Linux下的C编程实战之四(下)
·Linux下的C编程实战之开发平台搭
·资深Linux程序员的开发经验谈(下
·资深Linux程序员的开发经验谈(上
·黑客高级技巧 Linux后门技术及实
·黑客高级技巧 Linux后门技术及实
·Linux系统下C语言编程工具详细介
·Linux系统下C语言编程工具详细介
·Linux系统下的C语言开发都需要学
  相关信息
copy right @ 百家拳软件项目研究室 2007 辽ICP备07011763