服务器之家:专注于服务器技术及软件下载分享
分类导航

Linux|Centos|Ubuntu|系统进程|Fedora|注册表|Bios|Solaris|Windows7|Windows10|Windows11|

服务器之家 - 服务器系统 - Linux - 关于进程间通信的Linux小程序

关于进程间通信的Linux小程序

2021-11-04 15:35net小伙 Linux

这篇文章主要为大家详细介绍了一个关于进程间通信的Linux小程序,主要利用共享内存实现进程间通信,使用管道实现进程间竞争关系,感兴趣的朋友可以参考一下

利用工作之余为小伙伴写了份作业,关于进程间通信的。题目如下:

“父进程从键盘上接受1000个数据,对其求和sum1,子进程对这1000个数平方和sum2,结果传给父进程,父进程将sum1+sum2后,打印结果。”

要求:用大小为10的共享区传递1000个数据;子进程用消息机制将sum2传给父进程。 

主要利用共享内存实现进程间通信,使用管道实现进程间竞争关系,FreeBSD下测试通过。代码如下:时间有限,有可能有些不足,希望高手给予指点。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <signal.h>
 
const int key = 0x12345678;
static int pfd1[2], pfd2[2];
 
#define SHM_LEN (10*1024)
#define VAL_NUM 5
 
int init_shm() {
 int shmid = -1;
 
 shmid = shmget((key_t)key, SHM_LEN, 0666 | IPC_CREAT);
 if (shmid < 0) {
  printf("shmget failed!\n");
  exit(-1);
 }
 
 return shmid;
}
 
void cancel_shm(int shmid) {
 if (shmctl(shmid, IPC_RMID, 0) == -1) {
  printf("shmctl failed!\n");
  exit(-1);
 }
 printf("cancel_shm successfully!\n");
}
 
void *shm_get(int shmid) {
 void *mem = NULL;
 
 mem = shmat(shmid, 0, 0);
 if (mem == (void *)-1) {
  printf("shmat failed!\n");
  exit(-1);
 }
 
 return mem;
}
 
int get_val(int *val, int num) {
 int i;
 for (i = 0; i < num; i++) {
  printf("please input a num:");
  scanf("%d", val + i);
 }
}
void show_val (int *val, int num) {
 int i;
 for (i = 0; i < num; i++) {
  printf("%d\t", *(val + i));
 }
 printf("\n");
}
 
int add_val (int *val, int num) {
 int result = 0;
 int i;
 
 for (i = 0; i < num; i++) {
  result += *(val + i);
 }
 
 return result;
}
 
int square_val (int *val, int num) {
 int result = 0;
 int i, tmp;
 
 for (i = 0; i < num; i++) {
  tmp = *(val + i);
  result += (tmp * tmp);
 }
 
 return result;
}
 
void TELL_WAIT (void) {
 if (pipe(pfd1) < 0 || pipe(pfd2) < 0) {
  printf("pipe error!\n");
  exit(-1);
 }
}
 
void TELL_PARENT (pid_t pid) {
 if (write(pfd2[1], "c", 1) != 1) {
  printf("write error!\n");
  exit(-1);
 }
}
 
void WAIT_PARENT (void) {
 char c;
 
 if (read(pfd1[0], &c, 1) != 1) {
  printf("read error!\n");
  exit(-1);
 }
}
 
void TELL_CHILD (pid_t pid) {
 if (write(pfd1[1], "p", 1) != 1) {
  printf("write error!\n");
  exit(-1);
 }
}
 
void WAIT_CHILD (void) {
 char c;
 
 if (read(pfd2[0], &c, 1) != 1) {
  printf("read error!\n");
  exit(-1);
 }
}
 
int main(int argc, char *argv[]) {
 void *mem = NULL;
 int shmid = -1;
 pid_t pid = -1;
 int val[VAL_NUM];
 int result = 0;
 
 shmid = init_shm();
 
 TELL_WAIT();
 if ((pid = fork()) < 0) {  //error
  printf("fork error!\n");
  exit(-1);
 } else if (pid == 0) {   //child
  int result = 0;
 
  WAIT_PARENT();
 
  mem = shm_get(shmid);  //get share memery
 
  memcpy(val, mem, sizeof(int) * VAL_NUM);
  result = square_val(val, VAL_NUM);
 
  *(int *)((void *)mem + SHM_LEN - 4) = result;
 
  TELL_PARENT(pid);
 
  exit(1);
 } else {      //parent
  int child_result = 0;
 
  mem = shm_get(shmid);  //get share memery
  get_val(val, VAL_NUM);  //get user input
  memcpy(mem, val, sizeof(int) * VAL_NUM); //copy user input to share memery
 
  TELL_CHILD(pid);
 
  result = add_val(val, VAL_NUM);
 
  WAIT_CHILD();
  child_result = *(int *)((void *)mem + SHM_LEN - 4);
  printf("result:%d, child_result:%d, all:%d\n", result, child_result, result + child_result);
 }
 
 cancel_shm(shmid);
 
 return 0;
}

以上就是本文的全部内容,希望对大家的学习有所帮助。

延伸 · 阅读

精彩推荐
  • LinuxLinux系统中strace命令的使用教程

    Linux系统中strace命令的使用教程

    这篇文章主要介绍了Linux系统中strace命令的使用教程,strace命令用于追踪和统计系统调用信息,需要的朋友可以参考下...

    开源中文社区2372019-07-15
  • Linuxlinux之间文件传输方法

    linux之间文件传输方法

    linux 的 scp 命令 可以 在 linux 之间复制 文件 和 目录,需要的朋友可以参考下。 ...

    Linux教程网4172020-03-11
  • LinuxLinux系统中使用cmp和comm命令来比较两个文件

    Linux系统中使用cmp和comm命令来比较两个文件

    这篇文章主要介绍了Linux系统中使用cmp和comm来比较两个文件的方法,注意两个命令使用功能上的不同,需要的朋友可以参考下...

    Linux命令手册6202019-06-25
  • Linuxlinux下设定环境变量的方法介绍

    linux下设定环境变量的方法介绍

    在linux下设定环境变量时,如果只是临时用一下,可以直接在shell下用set或export命令设定环境变量,如果希望此环境变量每次开机或打开 shell时自动设定而无...

    Linux教程网3302019-12-19
  • LinuxLinux 快捷键使用

    Linux 快捷键使用

    命令运行时使用CTRL+Z,强制当前进程转为后台,并使之停止. 1. 使进程恢复运行(后台) (1)使用命令bg Example: zuii@zuii-desktop:~/unp/tcpcliserv$ ./tcpserv01 *这里使用CTRL...

    Linux教程网2692020-04-08
  • Linuxyum命令什么方法(更新软件、删除软件等)

    yum命令什么方法(更新软件、删除软件等)

    这篇文章主要介绍了yum常用命令介绍,包括更新软件、仅安装指定的软件、查询软件信息 、删除软件等方法,需要的朋友可以参考下 ...

    Linux命令大全4932019-11-12
  • Linuxlinux上传并配置jdk和tomcat的教程详解

    linux上传并配置jdk和tomcat的教程详解

    这篇文章主要介绍了linux上传并配置jdk和tomcat的操作方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考...

    never-ljy2172020-07-20
  • Linuxlinux查询历史记录命令history的用法介绍

    linux查询历史记录命令history的用法介绍

    有时候我们需要在执行大量命令操作的时候,需要查询曾经用过的命令,那么就需要用history这个命令来实现 ...

    linux命令大全15542019-11-15