2015年5月25日星期一

(十二) 一起学 Unix 环境高级编程 (APUE) 之 进程间通信(IPC) - yuhuashi

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
(十二) 一起学 Unix 环境高级编程 (APUE) 之 进程间通信(IPC) - yuhuashi  阅读原文»

.

.

.

.

.

目录

(一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO

(二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO

(三) 一起学 Unix 环境高级编程 (APUE) 之 文件和目录

(四) 一起学 Unix 环境高级编程 (APUE) 之 系统数据文件和信息

(五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境

(六) 一起学 Unix 环境高级编程 (APUE) 之 进程控制

(七) 一起学 Unix 环境高级编程 (APUE) 之 进程关系 和 守护进程

(八) 一起学 Unix 环境高级编程 (APUE) 之 信号

(九) 一起学 Unix 环境高级编程 (APUE) 之 线程

(十) 一起学 Unix 环境高级编程 (APUE) 之 线程控制

(十一) 一起学 Unix 环境高级编程 (APUE) 之 高级 IO

(十二) 一起学 Unix 环境高级编程 (APUE) 之 进程间通信(IPC)

在第一篇博文中我们介绍过,进程间通信(IPC) 分为 PIPE(管道)、Socket(套接字) 和 XSI(System V)。XSI 又分为 msg(消息队列)、sem(信号量数组) 和 shm(共享内存)。

这些手段都是用于进程间通讯的,只有进程间通讯才需要借助第三方机制,线程之间的通讯是不需要借助第三方机制的,因为线程之间的地址空间是共享的。

管道分为命名管道(FIFO)和匿名管道(PIPE),无论是哪种管道,都是由内核帮你创建和维护的。

管道的特点:

1.管道是半双工的,即同一时间数据只能从一端流向另一端。试想,如果一个管道从两边同时输入和输出数据,那么管道里的数据就乱了。

2.管道的两端一端作为读端,一端作为写端。

3.管道具有自适应的特点,默认会适应速度比较慢的一方,管道被写满或读空时速度快的一方会自动阻塞。

pipe(2) 函数

1 pipe - create pipe
2
3 #include <unistd.h>
4
5 int pipe(int pipefd[2]);

pipe(2) 用于创建管道,pipefd 是一个数组,表示管道的两端文件描述符,pipefd[0] 端作为读端,pipefd[1] 端作为写端

pipe(2) 产生的是匿名管道,在磁盘的任何位置上找不到这个管道文件,而且匿名管道只能用于具有亲缘关系的进程之间通信

一般情况有亲缘关系的进程之间使用管道进行通信时,会把自己不用的一端文件描述符关闭。

下面是创建匿名管道在父子进程之间传送了一个字符串“Hello”的小栗子。

1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4
5 #include <sys/types.h>
6 #include <sys/wait.h>
7
8 #define BUFSIZE 1024
9
10 int main()
11 {
12 int pd[2];
13 char buf;
14 pid_t pid;
15 int len;
16
17 // 创建匿名管道
18 if(pipe(pd) < 0)
19 {
20 perror("pipe()");
21 exit(1);
22 }
23
24 // 创建子进程
25 pid = fork();
26 if(pid < 0)
27 {
28 perror("fork()");
29 exit(1);
30 }
31 if(pid == 0) { // 子进程 读取管道数据
32 // 关闭写端
33 close(pd[1]);
34 // 从管道中读取数据,如果子进程比父进程先被调度会阻塞等待数据写入
35 len = read(pd[0],buf,BUFSIZE);
36 puts(buf);
37 /* 管道是 fork(2) 之前创建的,
38 * 父子进程里都有一份,
39 * 所以退出之前要确保管道两端都关闭
40 */
41 close(pd[0]);
42 exit(0);
43 } else { // 父进程 向管道写入数据
44 close(pd[0]);
45 write(pd[1],"Hello!",6);
46 close(pd[1]);
47 wait(NULL);
48 exit(0);
49 }
50 }

在上面的栗子中,父进程创建了一个匿名管道,在 pd[2] 数组中凑齐了读写双方,子进程同样继承了具有读写双方的数组 pd[2]。

父进程先关闭管道的读端然后向管道中写入数据,然后将用完的写端也关闭,等待子进程消亡并为其收?div style="border-bottom:1px solid #aaa;margin-bottom:25px">xUtils框架的使用详解 - 杰瑞教育  阅读原文»

一、xUtils简介

  xUtils 最初源于Afinal框架,进行了大量重构,使得xUtils支持大文件上传,更全面的http请求协议支持(10种谓词),拥有更加灵活的ORM,更多的事件注解支持且不受混淆影响...

  xUtils最低兼容android 2.2 (api level 8)。当前xUtils主要有四大模块:

  DbUtils模块

android中的orm框架,一行代码就可以进行增删改查;

支持事务,默认关闭;

可通过注解自定义表名,列名,外键,唯一性约束,NOT NULL约束,CHECK约束等(需要混淆的时候请注解表名和列名);

支持绑定外键,保存实体时外键关联实体自动保存或更新;

  ViewUtils模块

android中的ioc框架,完全注解方式就可以进行UI,资源和事件绑定;

新的事件绑定方式,使用混淆工具混淆后仍可正常工作;

  HttpUtils模块

支持同步,异步方式的请求;

支持大文件上传,上传大文件不会oom;

支持GET,POST,PUT,MOVE,COPY,DELETE,HEAD,OPTIONS,TRACE,CONNECT请求;

  BitmapUtils模块

加载bitmap的时候无需考虑bitmap加载过程中出现的oom和android容器快速滑动时候出现的图片错位等现象;

支持加载网络图片和本地图片;

内存管理使用lru算法,更好的管理bitmap内存;

二、DbUtils使用方法
DbUtils db = DbUtils.create(this);
User user
= new User(); //这里需要注意的是User对象必须有id属性,或者有通过@ID注解的属性
user.setEmail("jerehedu@qq.com");
user.setName(
"jerehedu");
db.save(user);
// 使用saveBindingId保存实体时会为实体的id赋值

...
// 查找
Parent entity = db.findById(Parent.class, parent.getId());
List
<Parent> list = db.findAll(Parent.class);//通过类型查找

Parent Parent
= db.findFirst(Selector.from(Parent.class).where("name","=","test"));

// IS NULL
Parent Parent = db.findFirst(Selector.from(Parent.class).where("name","=", null));
// IS NOT NULL
Parent Parent = db.findFirst(Selector.from(Parent.class).where("name","!=", null));

// WHERE id<54 AND (age>20 OR age<30) ORDER BY id LIMIT pageSize OFFSET pageOffset
List<Parent> list = db.findAll(Selector.from(Parent.class)
.where(
"id" ,"<", 54)
.and(WhereBuilder.b(
"age", ">", 20).or("age", " < ", 30))
.orderBy(
"id")
.limit(pageSize)
.offset(pageSize
* pageIndex));

// op为"in"时,最后一个参数必须是数组或Iterable的实现类(例如List等)
Parent test = db.findFirst(Selector.from(Parent.class).where("id", "in", new int[]{1, 2, 3}));
// op为"between"时,最后一个参数必须是数组或Iterable的实现类(例如List等)
Parent test = db.findFirst(Selector.from(Parent.class).where("id", "between", new String[]{"1", "5"}));

DbModel dbModel
= db.findDbModelAll(Selector.from(Parent.class).select("name"));//select("name")只取出name列
List<DbModel> dbModels = db.findDbModelAll(Selector.from(Parent.class).groupBy("name").select("name", "count(name)"));
...

List
<DbModel> dbModels = db.findDbModelAll(sql); // 自定义sql查询
db.execNonQuery(sql) // 执行自定义sql
三、HttpUtils使用方法
HttpUtils http = new HttpUtils();
http.send(HttpRequest.HttpMethod.GET,
"http://www.jerehedu.com",
new RequestCallBack<String>(){
@Override
public void onLoading(long total, long current, boolean isUploading) {
testTextView.setText(current
+ "/" + total);
}

@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
textView.setText(responseInfo.result);
}

@Override
public void onStart() {
}

@Override
public void

没有评论:

发表评论