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 ;
}

最新文章

  1. Size Balance Tree(SBT模板整理)
  2. (原创)Xilinx的ISE生成模块ngc网表文件
  3. python 输出十六进制中文乱码
  4. 关于windows phone教务在线客户端
  5. JAVA Day6
  6. View (五)自定义View的实现方法
  7. .net学习之多线程、线程死锁、线程通信 生产者消费者模式、委托的简单使用、GDI(图形设计接口)常用的方法
  8. 小结:ac自动机
  9. 【leetcode❤python】171. Excel Sheet Column Number
  10. 解决ImportError: cannot import name HTTPConnection的方法
  11. wampserver 2.2装好后80端口未被占用,却打不开localhost
  12. strcat()的编写
  13. Javascript中undefined,NaN等特殊比较
  14. MySql 安装及0基础使用具体解释
  15. 百度前端面试题-类似slack的在线聊天室
  16. Python s12 Day1 笔记及作业
  17. Linux跑脚本用sh和./有什么区别?(转)
  18. L1-Day5
  19. puppetdb搭建
  20. ImageMagick - MAGICK_CODER_MODULE_PATH 测试结果, 很受伤

热门文章

  1. 关于微信公账号H5 API 调用的坑 BUG
  2. LINQPad 编译调试C#代码的工具推荐
  3. AWK入门指南
  4. 异常:Neither BindingResult nor plain target object for bean name &#39;command&#39; available as request attribute
  5. reactnative 原生组件通信原理
  6. miniui dataGrid drawcell事件
  7. oracle数据库恢复归档脚本
  8. new ,malloc
  9. 20145238-荆玉茗《网络对抗技术》-Web基础
  10. 新建oracle实例