Binder是什么?
- 进程间通信机制
- 也是一个驱动
- Binder.java 它实现了Ibinder(只要实现了Ibinder 接口 就具备了跨进程通讯的能力) —这个是为什么昵?
多进程的原因
-
为了 占用更大的内存空间, 每个进程拥有一个虚拟机,
-
实现风险隔离,,每个进程相当一个单独的APP,将一个比较危险的动作放到单独的进程中,这样就算一个进程挂掉了 也不影响应用。
Linux 进程间通讯的方式
管道 信号量 文件管理 共享内存 soekcet
Binder 优点:
1.拷贝一次。
2.基于C/S 架构
3.为每个APP分配UID 同时支持实名和匿名。实名 例如 系统服务 可以通过getsystemservice() 获取。匿名的话就是自己获取的服务。
共享内存: 无需拷贝,
Socket:拷贝两次。
Binder是性能小于共享内存 优于其他IPC。
Binder 机制的
接收进程和内核进程就是通过MMAP()函数实现了共享同一块物理内存地址。
发送进程(copy_from_user)将信息发送到内核进程,拷贝一次。相当与直接拷贝到接受进程。
用户空间不可直接操作文件。先拷贝的内核空间 在拷贝到文件。
MMAP 可以实现将用户空间直接映射到文件中。这样操作虚拟内存将相当与直接在操作文件。
MMAP的原理:就是一个虚拟内存区域与一个指定的物理内存关联起来,这样操作虚拟内存的时候就相当与直接操作了这个物理内存。 如果没有MMAP,在虚拟内存中操作的存储动作,就相当于存在一个随机的地址。这样子的共享内存才能减少拷贝次数。
1. m_fd = open(file.c_str(), ); //打开一个文件夹
2. m_ptr = mmap(size,0,...,m_fd) //将内存的虚拟空间和文件关联上,并返回指向虚拟空间的内存地址。
3. memcpy(m_ptr, date.data(), date.size()) 将size大小的数据拷贝到m_ptr指向的虚拟内存中,这种相当于直接将内容拷贝到文件中
binder驱动的启动流程
Linux 里面一切皆文件
binder驱动就相当于一个文件。
static int __init binder_init(void)
{
int ret;
char *device_name, *device_names;
struct binder_device *device;
struct hlist_node *tmp;
//创建名为binder的单线程的工作队列
binder_deferred_workqueue = create_singlethread_workqueue("binder");
if (!binder_deferred_workqueue)
return -ENOMEM;
binder_debugfs_dir_entry_root = debugfs_create_dir("binder", NULL);
if (binder_debugfs_dir_entry_root)
binder_debugfs_dir_entry_proc = debugfs_create_dir("proc",
binder_debugfs_dir_entry_root);
if (binder_debugfs_dir_entry_root) {
debugfs_create_file("state",
S_IRUGO,
binder_debugfs_dir_entry_root,
NULL,
&binder_state_fops);
debugfs_create_file("stats",
S_IRUGO,
binder_debugfs_dir_entry_root,
NULL,
&binder_stats_fops);
debugfs_create_file("transactions",
S_IRUGO,
binder_debugfs_dir_entry_root,
NULL,
&binder_transactions_fops);
debugfs_create_file("transaction_log",
S_IRUGO,
binder_debugfs_dir_entry_root,
&binder_transaction_log,
&binder_transaction_log_fops);
debugfs_create_file("failed_transaction_log",
S_IRUGO,
binder_debugfs_dir_entry_root,
&binder_transaction_log_failed,
&binder_transaction_log_fops);
}