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 调用过程吧。

参考:https://www.jianshu.com/p/494c2d32e3bb

5)Shared Memory  & sem
这个也是网上找的,忘了在哪里找的。
sem.h
#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 ;
}
read.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;
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

linux进程的休眠(等待队列)

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的更多相关文章

  1. Linux IPC实践(1) -- 概述

    进程的同步与互斥 进程同步: 多个进程需要相互配合共同完成一项任务. 进程互斥: 由于各进程要求共享资源,而且有些资源需要互斥使用,因此各进程间竞争使用这些资源,进程的这种关系为进程的互斥;系统中某些 ...

  2. Linux IPC之共享内存C 事例

    Linux IPC之共享内存 标签: linuxrandomnull工作 2011-08-25 11:52 4123人阅读 评论(0) 收藏 举报  分类: Linux(3)  读书札记(3)  版权 ...

  3. Linux IPC System V 共享内存

    模型 #include<sys/types.h> #include<sys/ipc.h> #include<sys/shm.h> ftok() //获取key值 s ...

  4. linux IPC总结——管道

    管道 管道是unix ipc的最古老形式,是一种在内存中的特殊文件,只能在具有公共祖先的进程之间使用(即父子进程,兄弟进程). 管道由pipe函数创建 #include <unistd.h> ...

  5. Linux IPC实践(11) --System V信号量(1)

    信号量API #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> int semget ...

  6. Linux IPC实践(9) --System V共享内存

    共享内存API #include <sys/ipc.h> #include <sys/shm.h> int shmget(key_t key, size_t size, int ...

  7. Linux IPC实践(8) --共享内存/内存映射

    概述 共享内存区是最快的IPC形式.一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据(如图). 共享内存 VS ...

  8. Linux IPC实践(7) --Posix消息队列

    1. 创建/获取一个消息队列 #include <fcntl.h> /* For O_* constants */ #include <sys/stat.h> /* For m ...

  9. Linux IPC基础(System V)

    简介 IPC 主要有消息队列.信号量和共享内存3种机制.和文件一样,IPC 在使用前必须先创建,使用 ipcs 命令可以查看当前系统正在使用的 IPC 工具: 由以上可以看出,一个 IPC 至少包含 ...

随机推荐

  1. javascript不可用的问题探究

    昨天在Twitter上的一些有趣的讨论中, 我发现人们对于Web应用和站点对javascript的依赖普遍存在一种疑惑. 这种疑惑一直都存在, 而对我而言, 这个问题随着浏览技术的飞跃发展而集中爆发了 ...

  2. Java的图形界面依然是跨平台的

    Awt:抽象窗口工具箱,它由三部分组成: ①组件:界面元素: ②容器:装载组件的容器(例如窗体): ③布局管理器:负责决定容器中组件的摆放位置. 图形界面的应用分四步: ① 选择一个容器: ⑴wind ...

  3. java----内部类与匿名内部类的各种注意事项与知识点

    Java 内部类分四种:成员内部类.局部内部类.静态内部类和匿名内部类.1.成员内部类: 即作为外部类的一个成员存在,与外部类的属性.方法并列.注意:成员内部类中不能定义静态变量,但可以访问外部类的所 ...

  4. 10个网页设计师必备的CSS技巧(转)

    英文原文:10 Essential CSS Rules for Web Designers CSS是网页设计师的基础,对CSS的了解能使他们能够设计出更加美观别致的网页.使用CSS技巧来巧妙地处理CS ...

  5. 【noip模拟题】天神下凡(贪心)

    vijos某次模拟赛原题... 处理出每个圆的一级祖先就行了... 其实没有那么麻烦,贪心即可出解. 我们将每个圆转换成线段后按左端点小右端点大的方法排序 然后维护一个栈: 对于每一个圆i 如果栈顶右 ...

  6. gomobile build

    You need to set the NDK path in gomobile init using the -ndk flag - if you follow these instructions ...

  7. NPOI例子

    例子链接:http://www.cnblogs.com/atao/tag/NPOI/default.html?page=1

  8. CSS之各种居中

    本博客讨论居中情况设定为 总宽度不定,内容宽度不定 的情况.(改变大小时,仍然居中). 特别说明:在元素设置 position:absolute; 来设置居中效果时,除去博客下介绍的css3方法外,还 ...

  9. Visual Studio Code调试node.js:无法在PATH上找到运行时的node

    首先,环境变量Path中加入nodejs的路径: 验证nodejs是否已经加入环境变量: 接着,重新启动Visual Studio Code, 试一下,是不是好了~   附录:Visual Studi ...

  10. 【IIS】IIS 7.0/7.5 绑定

    window 7 IIS 7.0/7.5 默认站点不存在,甚至Http的绑定类型也无法选择,而绑定类型是空的,或者是别的.此时IIS无法正常创建IIS站点,而创建IIS站点的页面也不是通常的页面,此时 ...