1、线程间通信(参考安卓源码InputTransport.cpp)

#include <pthread.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h> static const size_t SOCKET_BUFFER_SIZE = * ; void *pthread_1(void *arg)
{
int fd = *((int *)arg);
char buf[];
int len;
int cnt = ; while () {
len = sprintf(buf, "hello, main pthread, cnt = %d", cnt++);
write(fd, buf, len); len = read(fd, buf, );
buf[len] = '\0';
printf("%s\n", buf);
sleep();
}
return NULL;
} int main(int argc, char **argv)
{
int sockets[];
pthread_t thread_id;
if (socketpair(AF_UNIX, SOCK_SEQPACKET, , sockets)) {
printf("socketpair error\n");
return -;
}
int bufferSize = SOCKET_BUFFER_SIZE;
/* 创建4个buff, sockets[0]的发送buff和接收buff; sockets[1]的发送buff和接收buff*/
setsockopt(sockets[], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
setsockopt(sockets[], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
setsockopt(sockets[], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
setsockopt(sockets[], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
int res = pthread_create(&thread_id, NULL, pthread_1, (void *)(&sockets[]));
if (res) {
printf("pthread_create error\n");
return -;
}
int fd = sockets[];
char buf[];
int len;
int cnt = ; while () {
len = sprintf(buf, "hello, pthread1, cnt = %d", cnt++);
write(fd, buf, len); //将buf中的内容通过fd句柄发送到snd buff len = read(fd, buf, ); //通过读fd中的rcv buff, 将内容读到buf中,然后打印出来
buf[len] = '\0';
printf("%s\n", buf);
sleep();
}
return ;
}

打印信息:

再打开一个终端查看进程:ps  -A 查看socketpair的pid为6065

cd /proc/6065

ls task

2、父子进程间通信

需要注意的是fd == 0是子进程,fd > 0 是父进程

#include <unistd.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h> static const size_t SOCKET_BUFFER_SIZE = * ; int main(int argc, char **argv)
{
int sockets[];
if (socketpair(AF_UNIX, SOCK_SEQPACKET, , sockets)) {
printf("socketpair error\n");
return -;
}
int bufferSize = SOCKET_BUFFER_SIZE;
setsockopt(sockets[], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
setsockopt(sockets[], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
setsockopt(sockets[], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
setsockopt(sockets[], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
pid_t fd = fork();if (fd == ) {
/* 子进程 */
int fd = sockets[];
char buf[];
int len;
int cnt = ;
while () {
len = sprintf(buf, "hello, father pid, cnt = %d", cnt++);
write(fd, buf, len); len = read(fd, buf, );
buf[len] = '\0';
printf("%s\n", buf);
sleep();
}
}
if (fd > ) {
/* 父进程 */
int fd = sockets[];
char buf[];
int len;
int cnt = ;
while () {
len = sprintf(buf, "hello, child pid, cnt = %d", cnt++);
write(fd, buf, len); len = read(fd, buf, );
buf[len] = '\0';
printf("%s\n", buf);
sleep();
} } return ;
}

运行结果:

查看进程:ps -A   有2个名为fork的进程

3、使用binder传递文件句柄,实现进程间通信

4、看得出来socketpair实现了进程或线程间的双全工通信

而管道一般是半全工通信,要双全工就得创建2个管道

#include <unistd.h>
#include <stdio.h> int main(int argc, char **argv)
{ int fd[]; //fd[0]是读,fd[1]是写
int fd2[];
int res = pipe(fd);
if (res) {
printf("create pipe error\n");
return -;
}
res = pipe(fd2);
if (res) {
printf("create pipe2 error\n");
return -;
}
pid_t pid = fork();
if (pid > ) {
char buf[];
int len;
while () {
len = sprintf(buf, "hello my child!");
buf[len] = '\0';
write(fd[], buf, len);
len = read(fd2[], buf, );
buf[len] = '\0';
printf("%s\n", buf);
sleep();
}
}
else if (pid == ) {char buf[];
int len;
while () {
len = read(fd[], buf, );
buf[len] = '\0';
printf("%s\n", buf);
len = sprintf(buf, "hello my father!");
buf[len] = '\0';
write(fd2[], buf, len);
sleep();
} } return ;
}

同样pipe也可以用于线程间通信:

#include <unistd.h>
#include <stdio.h>
#include <pthread.h> struct pipe_rw {
int fd_r;
int fd_w;
}; void *thread_handle(void *arg)
{
struct pipe_rw *pPipeRw = (struct pipe_rw *)arg;
char buf[];
int len;
while () {
len = read(pPipeRw->fd_r, buf, );
buf[len] = '\0';
printf("%s\n", buf);
len = sprintf(buf, "hello my father");
buf[len] = '\0';
write(pPipeRw->fd_w, buf, len);
sleep();
}
} int main(int argc, char **argv)
{ int fd[]; //fd[0]是读,fd[1]是写
int fd2[];
int res = pipe(fd);
if (res) {
printf("create pipe error\n");
return -;
}
res = pipe(fd2);
if (res) {
printf("create pipe2 error\n");
return -;
}
pthread_t thread;
struct pipe_rw pipe_arg;
pipe_arg.fd_r = fd[];
pipe_arg.fd_w = fd2[];
pthread_create(&thread, NULL, thread_handle, &pipe_arg);
char buf[];
int len;
while () {
len = sprintf(buf, "hello my child");
buf[len] = '\0';
write(fd[], buf, len);
len = read(fd2[], buf, );
buf[len] = '\0';
printf("%s\n", buf);
sleep();
} return ;
}

命名管道:

write:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h> #define PATH "./myfifo" int main(int argc, char **argv)
{
int res = mkfifo(PATH, |S_IFIFO); //在当前目录下创建一个名为myfifo的管道
if (res) {
printf("create named pipe error\n");
return -;
}
int fd = open(PATH, O_WRONLY); //命名管道是可以直接open的
if (fd < ) {
printf("open %s error\n", PATH);
return -;
}
char buf[];
int len;
len = sprintf(buf, "hello world");
while () {
write(fd, buf, len);
sleep();
}
close(fd);
return ;
}

read:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h> #define PATH "./myfifo" int main(int argc, char **argv)
{
int fd = open(PATH, O_RDONLY);
if (fd < ) {
printf("open %s error\n", PATH);
return -;
}
char buf[];
int len;
while () {
len = read(fd, buf, 512);
buf[len] = '\0';
printf("%s\n", buf);
}
close(fd);
return ;
}

socketpair通信的更多相关文章

  1. linux 单机跨进程通信

    一般来说通过网络通信(比如tcp,udp)或者共享内存的方式肯定可以实现跨进程通信,但现在这里要说的是比较偏但实用的几个方法:利用unix域通信(普通网络连接),利用unix域通信(socketpai ...

  2. UNP学习 Unix域协议

    Unix域协议并不是一个实际的协议族,它只是在同一台主机上进行客户-服务器通信时,使用与在不同主机上的客户和服务器间通信时相同的API的一种方法. 当客户和服务器在同一台主机上时,Unix域协议是这套 ...

  3. socketpair创建双向通信的管道(全双工通信)

    Linux下socketpair介绍: socketpair创建了一对无名的套接字描述符(只能在AF_UNIX域中使用),描述符存储于一个二元数组,例如sv[2] .这对套接字可以进行双工通信,每一个 ...

  4. 线程之间的通信socketpair【学习笔记】【原创】

    平台信息:内核:linux3.1.0系统:android5.0平台:tiny4412 作者:庄泽彬(欢迎转载,请注明作者) 说明: 韦老师的安卓视频学习笔记 一.在一个进程中多个线程如何进行通信,主要 ...

  5. ZeroMQ(java)之I/O线程的实现与组件间的通信

    算是开始读ZeroMQ(java)的代码实现了吧,现在有了一个大体的了解,看起来实现是比较的干净的,抽象什么的不算复杂... 这里先来看看它的I/O线程的实现吧,顺带看看是如何实现组件的通信的.... ...

  6. socketpair理解

    转载:http://liulixiaoyao.blog.51cto.com/1361095/533469/ 今天跟人谈到socketpair的问题,晚上回来写了个程序验证下自己的猜测! 先说说我的理解 ...

  7. 【Chromium中文文档】跨进程通信 (IPC)

    跨进程通信 (IPC) 转载请注明出处:https://ahangchen.gitbooks.io/chromium_doc_zh/content/zh//General_Architecture/I ...

  8. UNIX网络编程——UNIX域套接字编程和socketpair 函数

    一.UNIX Domain Socket IPC socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket.虽然网络soc ...

  9. 输入系统:进程间双向通信(socketpair+binder)

    一.双向通信(socketpair) socketpair()函数用于创建一对无名的.相互连接的套接子,如果函数成功,则返回0,创建好的套接字分别是sv[0]和sv[1]:否则返回-1,错误码保存于e ...

随机推荐

  1. 【Leetcode】【Medium】Swap Nodes in Pairs

    Given a linked list, swap every two adjacent nodes and return its head. For example,Given 1->2-&g ...

  2. Markdown学习使用

    本文记录Markdown的基础应用. 一.基础知识 Markdown 是一种标记语言 文件后缀名:.md 编辑工具:VSCode(visual studio code) VSCode中预览模式快捷键: ...

  3. Toad for MySQL 7.3 Freeware异常 2017-01-09 15:14 115人阅读 评论(0) 收藏

    打开Toad出现如下异常信息: 解决办法: 重装.NET Framework4.0

  4. 使用Jmeter进行接口测试和压力测试的配置和使用

    1. Jmeter简介 Apache JMeter是Apache组织开发的基于Java的压力测试工具.用于对软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到其他测试领域. JMeter 可 ...

  5. Hive入门操作

    Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供类SQL查询功能.本文描述了HIve的一些基本操作,如有错误之处还请指出. 常用语法 #显示相关信息 sh ...

  6. 如何在SAP里创建configurable material物料主数据

    (1) 使用tcode CT04创建characteristic: assign 所有可能的color value: (2) 使用tcode CL02创建class. 类型选择300- variant ...

  7. 使用npoi插件将excel文件导出

    大致流程:前端使用URL地址的方式跳转到action后返回file类型数据 js: window.location.href = '/Home/index?Id=' + id 后台代码: /// &l ...

  8. poj2312 Battle City 【暴力 或 优先队列+BFS 或 BFS】

    题意:M行N列的矩阵.Y:起点,T:终点.S.R不能走,走B花费2,走E花费1.求Y到T的最短时间. 三种解法.♪(^∇^*) //解法一:暴力 //157MS #include<cstdio& ...

  9. Leetcode225 用栈实现队列

    大众思路: 用两个栈实现,记为s1,s2 1.元素入栈时,加入s1 2.元素出栈时,对s2进行判断,如果s2为空,则将全部s1元素弹出并压入到s2,然后从s2栈顶弹出一个元素:如果s2不为空,则直接从 ...

  10. 启动memcache

    "D:\SOFT\memcached-1.4.5-amd64\memcached-amd64\memcached.exe"