linux ipc/its
linux进程间双向消息队列
server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h> #include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h> typedef struct {
long type;
int id;
char buf[];
}msg_t; void *write_routine(void *arg)
{
key_t key = ftok("/",'a');
if(key==-)
{
perror("ftok");
} int msqid = msgget(key,IPC_CREAT|);
if(msqid==-)
{
perror("msgget");
} msg_t msg; while()
{
msg.type = ;
msg.id = ;
fgets(msg.buf,,stdin);
//msg_t msg={1,"login"};
int res = msgsnd(msqid,&msg,sizeof(msg.buf),IPC_NOWAIT);
} } void *read_routine(void *arg)
{
key_t key = ftok("/",'b');
if(key==-)
{
perror("ftok");
} int msqid = msgget(key,IPC_CREAT|);
if(msqid==-)
{
perror("msgget");
} msg_t msg;
while()
{
int res = msgrcv(msqid,&msg,sizeof(msg_t),,IPC_NOWAIT);
if(res==-){
//perror("msgrcv");
}
switch (msg.id) {
case : {
printf("%s\n",msg.buf);
break;
}
case : {
printf("%s\n",msg.buf);
break;
}
} msg.id = ; } } int main()
{
pthread_t wid;
pthread_t rid; int res = pthread_create(&wid,,write_routine,);
if(res){
printf("%s\n",strerror(res));
} int res2 = pthread_create(&rid,,read_routine,);
if(res2){
printf("%s\n",strerror(res2));
} pthread_join(wid,);
pthread_join(rid,); return ;
}
client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h> #include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h> typedef struct {
long type;
int id;
char buf[];
}msg_t; void *read_routine(void *arg)
{
key_t key = ftok("/",'a');
if(key==-)
{
perror("ftok");
} int msqid = msgget(key,IPC_CREAT|);
if(msqid==-)
{
perror("msgget");
} msg_t msg;
while()
{
int res = msgrcv(msqid,&msg,sizeof(msg_t),,IPC_NOWAIT);
if(res==-){
//perror("msgrcv");
}
switch (msg.id) {
case : {
printf("%s\n",msg.buf);
break;
}
case : {
printf("%s\n",msg.buf);
break;
}
} msg.id = ;
} } void *write_routine(void *arg)
{
key_t key = ftok("/",'b');
if(key==-)
{
perror("ftok");
} int msqid = msgget(key,IPC_CREAT|);
if(msqid==-)
{
perror("msgget");
} msg_t msg;
msg.type = ;
msg.id = ;
//msg_t msg={1,"login"};
while()
{
fgets(msg.buf,,stdin);
int res = msgsnd(msqid,&msg,sizeof(msg_t),IPC_NOWAIT);
}
} int main()
{
pthread_t wid;
pthread_t rid; int res = pthread_create(&wid,,write_routine,);
if(res){
printf("%s\n",strerror(res));
} int res2 = pthread_create(&rid,,read_routine,);
if(res2){
printf("%s\n",strerror(res2));
} pthread_join(wid,);
pthread_join(rid,); return ;
}
Makefile
.PHONY:all
all:server client
server:server.c
gcc -o server server.c -pthread
client:client.c
gcc -o client client.c -pthread
.PHONY:clean
clean:
rm -f server client
https://blog.csdn.net/weixin_41215479/article/details/81511188
线程间消息
https://blog.csdn.net/qq_26391203/article/details/75220449
将共享内存改造成一个共享fifo,酷 !
https://github.com/zhoudd1/linux_ipc/tree/master/shm_fifo
message queue
https://github.com/mdminhazulhaque/mqueue
1、nanomsg
nanomsg(ZeroMQ with C)
https://www.cnblogs.com/dong1/p/9213214.html
2、libmsgque
linux进程通信消息队列
https://gitee.com/fulinux/libmsgque
3、dbus
https://blog.csdn.net/quinta2008/article/details/78472170
linux ipc
1)signal
recv.c
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
void new_op(int,siginfo_t*,void*);
int main(int argc,char**argv)
{
struct sigaction act;
int sig;
pid_t pid; pid=getpid();
sig=atoi(argv[]); sigemptyset(&act.sa_mask);
act.sa_sigaction=new_op;
act.sa_flags=SA_SIGINFO;
if(sigaction(sig,&act,NULL)<)
{
printf("install sigal error\n");
}
while()
{
sleep();
printf("pid %d wait for the signal\n",pid);
}
}
void new_op(int signum,siginfo_t *info,void *myact)
{
printf("the int value is %d \n",info->si_int);
}
send.c
#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/types.h>
main(int argc,char**argv)
{
pid_t pid;
int signum;
union sigval mysigval;
signum=atoi(argv[]);
pid=(pid_t)atoi(argv[]);
mysigval.sival_int=;
if(sigqueue(pid,signum,mysigval)==-)
printf("send error\n");
sleep();
}
gcc -o recv recv.c
gcc -o send send.c
./recv 1
./send 1 39823
参考 https://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index2.html
2)message queue
recv.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h> #define MSG_LEN 100
#define MSG_KEY 1234 //msg_queue
typedef struct
{
long int type;
char data[MSG_LEN];
}msg_t; static int msgid; //msg queue init
int msg_queue_creat(key_t key)
{
msgid=msgget(key, | IPC_CREAT);
if(msgid==-)
{
fprintf(stderr,"msgget failed with error: %d\n",errno);
}
return ;
} int main()
{
msg_queue_creat(MSG_KEY); while(){ msg_t msg;
if(msgrcv(msgid, &msg, sizeof(msg_t), , IPC_NOWAIT) == -)
{
//fprintf(stderr,"msgrcv failed with error: %d\n",errno);
}
else printf("recv a message: %ld,%s\n",msg.type,msg.data); sleep();
}
}
send.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h> #define MSG_LEN 100
#define MSG_KEY 1234 //msg_queue
typedef struct
{
long int type;
char data[MSG_LEN];
}msg_t; static int msgid; //msg queue init
int msg_queue_creat(key_t key)
{
msgid=msgget(key, | IPC_CREAT);
if(msgid==-)
{
fprintf(stderr,"msgget failed with error: %d\n",errno);
}
return ;
} int main()
{
msg_queue_creat(MSG_KEY); while() {
msg_t msg={,"hello,world"};
if(msgsnd(msgid, &msg, sizeof(msg_t), IPC_NOWAIT) == -)
{
//fprintf(stderr,"msgsnd failed with error: %d\n",errno);
}
else printf("send a message\n");
sleep();
}
}
参考 https://www.ibm.com/developerworks/cn/aix/library/au-ipc/
3) semaphore (命名信号量)
有名信号量实现进程间同步功能(print2 先打印,再到 print1 打印)
print1.c
#include <fcntl.h> /* For O_* constants */
#include <sys/stat.h> /* For mode constants */
#include <semaphore.h>
#include <stdio.h> void print(sem_t *print1, sem_t *print2)
{
int i = ;
while()
{
sem_wait(print1);
i++;
printf("int print1 i = %d\n", i);
sem_post(print2);
}
} int main(int argc, char **argv)
{
sem_t *print1, *print2; print1 = sem_open("sem_print1", O_CREAT, , );
if(SEM_FAILED == print1)
{
perror("sem_open");
} print2 = sem_open("sem_print2", O_CREAT, , );
if(SEM_FAILED == print2)
{
perror("sem_open");
} print(print1, print2); return ;
}
print2.c
#include <fcntl.h> /* For O_* constants */
#include <sys/stat.h> /* For mode constants */
#include <semaphore.h>
#include <stdio.h> void print(sem_t *print1, sem_t *print2)
{
int i = ;
while()
{
sem_wait(print2);
i++;
printf("in print2 i = %d\n", i);
sleep();
sem_post(print1);
}
} int main(int argc, char **argv)
{
sem_t *print1, *print2; print1 = sem_open("sem_print1", O_CREAT, , );
if(SEM_FAILED == print1)
{
perror("sem_open");
} print2 = sem_open("sem_print2", O_CREAT, , );
if(SEM_FAILED == print2)
{
perror("sem_open");
} print(print1, print2); return ;
}
删除有名信号量示例代码如下:
#include <semaphore.h>
#include <stdio.h> void sem_del(char *name)
{
int ret; ret = sem_unlink(name);
if(ret < )
{
perror("sem_unlink");
}
} int main(int argc, char **argv)
{
sem_del("sem_print1"); //删除信号量文件sem_print1
sem_del("sem_print2"); //删除信号量文件sem_print2 return ;
}
makefile 代码如下:
all:
gcc sem_del.c -o sem_del -lpthread
gcc print1.c -o print1 -lpthread
gcc print2.c -o print2 -lpthread
clean:
rm sem_del print1 print2
运行程序时,先把有名信号量删除(sem_del),再分别运行 print1 和 print2
参考 https://www.cnblogs.com/jfyl1573/p/6820372.html
4)Shared Memory
write_shm.c
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
// 1. 创建 SHM
int shm_id = shmget(, , IPC_CREAT | );
if (shm_id != -) {
// 2. 映射 SHM
void* shm = shmat(shm_id, NULL, );
if (shm != (void*)-) {
// 3. 写 SHM
char str[] = "I'm share memory";
memcpy(shm, str, strlen(str) + );
// 4. 关闭 SHM
shmdt(shm);
} else {
perror("shmat:");
}
} else {
perror("shmget:");
}
return ;
}
read_shm.c
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h> int main() {
// 1. 获取 SHM
int shm_id = shmget(, , IPC_CREAT | ); if (shm_id != -) {
// 2. 映射 SHM
void* shm = shmat(shm_id, NULL, );
if (shm != (void*)-) {
// 3. 读取 SHM
char str[] = { };
memcpy(str, shm, strlen("I'm share memory"));
printf("shm = %s\n", (char *)shm);
// 4. 关闭 SHM
shmdt(shm);
} else {
perror("shmat:");
}
} else {
perror("shmget:");
}
if ( == shmctl(shm_id, IPC_RMID))
printf("delete shm success.\n");
return ;
}
编译:
gcc write_shm.c -o write_shm
gcc read_shm.c -o read_shm
先运行写入 SHM:
./write_shm
再运行读取 SHM:
./read_shm
I'm share memory
成功读取了写进程的写入的数据,虽然不是同步的,但是至少能够获取数据。最后再来分析分析内核中的 SHM 调用过程吧。
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h> void init_sem(int , int );
void delete_sem(int );
void sem_p(int );
void sem_v(int ); union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
}; void init_sem(int sem_id, int init_value)
{
union semun sem_union; sem_union.val = init_value; if (semctl(sem_id, , SETVAL, sem_union) < )
{
perror("failed to init_sem");
exit(-);
} return ;
} void delete_sem(int sem_id)
{
union semun sem_union; if (semctl(sem_id, , IPC_RMID, sem_union) < )
{
perror("failed to delete_sem");
exit(-);
} return ;
} void sem_p(int sem_id)
{
struct sembuf sem_b; sem_b.sem_num = ;
sem_b.sem_op = -;
sem_b.sem_flg = SEM_UNDO; if (semop(sem_id, &sem_b, ) < )
{
perror("failed to sem_p");
exit(-);
} return;
} void sem_v(int sem_id)
{
struct sembuf sem_b; sem_b.sem_num = ;
sem_b.sem_op = ;
sem_b.sem_flg = SEM_UNDO; if (semop(sem_id, &sem_b, ) < )
{
perror("failed to sem_v");
exit(-);
} return ;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>
#include "sem.h" typedef struct
{
double lon;
double lat;
double bd_lon;
double bd_lat;
}gps_info_t; int main(int argc, const char *argv[])
{
key_t key;
int shmid;
gps_info_t *gps = NULL;
int create_flag = ;
int sem_id; if ((key = ftok(".", 'a')) < )
{
perror("failed to get key");
exit(-);
} if ((sem_id = semget(key, , | IPC_CREAT | IPC_EXCL)) < )
{
if (errno == EEXIST)
{
if ((sem_id = semget(key, , )) < )
{
perror("failed to semget");
exit(-);
}
}
} init_sem(sem_id, ); if ((shmid = shmget(key, sizeof(gps_info_t), | IPC_CREAT | IPC_EXCL)) < )
{
if (errno == EEXIST)
{
if ((shmid = shmget(key, sizeof(gps_info_t), )) < )
{
perror("failed to create share memory");
exit(-);
}
}
else
{
perror("failed to shmget");
exit(-);
}
}
else
create_flag = ; if ((gps = shmat(shmid, NULL, )) == (void *)(-))
{
perror("failed to shmat");
exit(-);
} while()
{
sem_p(sem_id); printf("recv lon: %f\n", gps->lon);
printf("recv lat: %f\n", gps->lat);
sleep(); } if (create_flag == )
{
if (shmdt(gps) < )
{
perror("failed to shmdt");
exit(-);
} if (shmctl(shmid, IPC_RMID, NULL) == -)
{
perror("failed to delete share memory");
exit(-);
} delete_sem(sem_id);
} return ;
}
write.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>
#include "sem.h" typedef struct
{
double lon;
double lat;
}gps_info_t; int main(int argc, const char *argv[])
{
key_t key;
gps_info_t *gps = NULL;
int shmid;
int create_flag = ;
int sem_id; if ((key = ftok(".", 'a')) < )
{
perror("failed to get key");
exit(-);
} if ((sem_id = semget(key, , | IPC_CREAT | IPC_EXCL)) < )
{
if (errno == EEXIST)
{
if ((sem_id = semget(key, , )) < )
{
perror("failed to semget");
exit(-);
}
}
} init_sem(sem_id, ); if ((shmid = shmget(key, sizeof(gps_info_t), | IPC_CREAT | IPC_EXCL)) < )
{
if (errno == EEXIST)
{
if ((shmid = shmget(key, sizeof(gps_info_t), )) < )
{
perror("failed to shmget memory");
exit(-);
}
}
else
{
perror("failed to shmget");
exit(-);
}
}
else
create_flag = ; if ((gps = shmat(shmid, NULL, )) == (void *)(-))
{
perror("failed to shmat memory");
exit(-);
} while()
{
gps->lon += 1.1;
gps->lat += 2.2;
printf("send lon: %f\n", gps->lon);
printf("send lat: %f\n", gps->lat);
sem_v(sem_id); sleep();
} if (create_flag == )
{
if (shmdt(gps) < )
{
perror("failed to shmdt memory");
exit(-);
} if (shmctl(shmid, IPC_RMID, NULL) == -)
{
perror("failed to delete share memory");
exit(-);
} delete_sem(sem_id);
} return ;
}
Makefile
OBJ= write read
all: ${OBJ}
read:
gcc -g -o read read.c
write:
gcc -g -o write write.c
clean:
rm -f ${OBJ}
.PHONY: ${OBJ}
linux its
1) semaphore
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <pthread.h> #define err_sys(msg) \
do { perror(msg); exit(-); } while()
#define err_exit(msg) \
do { fprintf(stderr, msg); exit(-); } while() void *r1(void *arg)
{
sem_t* sems = (sem_t *)arg;
static int cnt = ; while(cnt--)
{
sem_wait(sems);
printf("I am in r1. I get the sems.\n");
}
} void *r2(void *arg)
{
sem_t* sems = (sem_t *)arg;
static int cnt = ; while(cnt--)
{
printf("I am in r2. I send the sems\n");
sem_post(sems);
sleep();
}
} int main(void)
{
sem_t sems;
pthread_t t1, t2; printf("sems size: %d\n", sizeof(sems));
/* sem_init()第二个参数为0表示这个信号量是当前进程的局部信号量,否则该信号
* 就可以在多个进程之间共享 */
if(sem_init(&sems, , ) < )
err_sys("sem_init error");
pthread_create(&t1, NULL, r1, &sems);
pthread_create(&t2, NULL, r2, &sems); pthread_join(t1, NULL);
pthread_join(t2, NULL);
sem_destroy(&sems); return ;
}
gcc -o pthread_sem_demo pthread_sem_demo.c -pthread
./pthread_sem_demo
参考 http://blog.csdn.net/u012796139/article/details/46743677
3) Linux 线程挂起与唤醒功能 实例
https://blog.csdn.net/waldmer/article/details/23422943
https://www.cnblogs.com/noaming1900/archive/2011/01/14/1935526.html
1)Linux下进程通信方式(共享内存,管道,消息队列,Socket)
https://www.cnblogs.com/lou424/p/5018966.html
2)Compare performance of IPC(Inter-Process Communication), include file, zeromq, socket, unixsocket, share-memory, msq-queue and so on
https://github.com/zhiyuan2007/IPC-performance-compare
3)linux线程间同步(Inter-Thread Synchronization)方式汇总
https://github.com/clpsz/linux-itss
linux ipc 扫盲
https://www.ibm.com/developerworks/cn/linux/l-ipc/
linux ipc/its的更多相关文章
- Linux IPC实践(1) -- 概述
进程的同步与互斥 进程同步: 多个进程需要相互配合共同完成一项任务. 进程互斥: 由于各进程要求共享资源,而且有些资源需要互斥使用,因此各进程间竞争使用这些资源,进程的这种关系为进程的互斥;系统中某些 ...
- Linux IPC之共享内存C 事例
Linux IPC之共享内存 标签: linuxrandomnull工作 2011-08-25 11:52 4123人阅读 评论(0) 收藏 举报 分类: Linux(3) 读书札记(3) 版权 ...
- Linux IPC System V 共享内存
模型 #include<sys/types.h> #include<sys/ipc.h> #include<sys/shm.h> ftok() //获取key值 s ...
- linux IPC总结——管道
管道 管道是unix ipc的最古老形式,是一种在内存中的特殊文件,只能在具有公共祖先的进程之间使用(即父子进程,兄弟进程). 管道由pipe函数创建 #include <unistd.h> ...
- Linux IPC实践(11) --System V信号量(1)
信号量API #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> int semget ...
- Linux IPC实践(9) --System V共享内存
共享内存API #include <sys/ipc.h> #include <sys/shm.h> int shmget(key_t key, size_t size, int ...
- Linux IPC实践(8) --共享内存/内存映射
概述 共享内存区是最快的IPC形式.一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据(如图). 共享内存 VS ...
- Linux IPC实践(7) --Posix消息队列
1. 创建/获取一个消息队列 #include <fcntl.h> /* For O_* constants */ #include <sys/stat.h> /* For m ...
- Linux IPC基础(System V)
简介 IPC 主要有消息队列.信号量和共享内存3种机制.和文件一样,IPC 在使用前必须先创建,使用 ipcs 命令可以查看当前系统正在使用的 IPC 工具: 由以上可以看出,一个 IPC 至少包含 ...
随机推荐
- C++中变量做数组长度
在Java中,这是完全可以的,比如我们运行如下程序: package cn.darrenchan.storm; import java.util.Arrays; public class Test { ...
- js 去掉数组中重复的对象
function deteleObject(obj) { // console.log(obj) var uniques = []; var stringify = {}; ; i < obj. ...
- 【BZOJ】1624: [Usaco2008 Open] Clear And Present Danger 寻宝之路(floyd)
http://www.lydsy.com/JudgeOnline/problem.php?id=1624 一开始我打算一个个最短路................................. 然 ...
- OSG 中 相交測试 模块 工作流程及原理
主要涉及三个类: 1. osgUtil::PolytopeIntersector // 详细不同算法实现类 2. osgUtil::IntersectionVisitor //用来遍历节点树的每一个节 ...
- RabbitMQ之Queues-5
工作队列的主要任务是:避免立刻执行资源密集型任务,然后必须等待其完成.相反地,我们进行任务调度:我们把任务封装为消息发送给队列.工作进行在后台运行并不断的从队列中取出任务然后执行.当你运行了多个工作进 ...
- 性能测试工具LoadRunner中进程运行和线程运行区别
loadrunner controller将使用驱动程序mmdrv运行Vuser.用户可以在controller的run-time setting中选择Vuser的运行方式, 是多进程方式or多线程方 ...
- IOC和AOP的一些基本概念
IOC和AOP的一些基本概念介绍 IOC 介绍 IOC 一.什么是IOC IoC就是Inversion of Control,控制反转.在Java开发中,IoC意味着将你设计好的类交给系统去控制,而不 ...
- 【RF库测试】对出错的处理
1.出错后继续执行:Run Keyword And Continue On Failure 2.获取关键字执行结果后继续执行:Run Keyword And Ignore Error 有时候,我们需要 ...
- __init__()
__init__() 是类的内置方法,用于初始化类的内部状态,当我们去实例化一个对象的时候,默认就会执行 __init__() 下面的语句,例子如下: #!/usr/bin/env python #- ...
- kotlin gradle的修改
Kotlin插件包括一个让我们配置Gradle的工具.但是我还是倾向于保持我对Gradle文件读写的控制权,否则它只会变得混乱而不会变得简单.不管怎么样,在使用自动工具之前知道它是怎么工作的是个不错的 ...