http://www.voidcn.com/article/p-hxvuiypm-mr.html

https://www.cnblogs.com/wuyida/archive/2013/02/03/6300020.html

程序示例 https://wenku.baidu.com/view/08bf51f7f61fb7360b4c657f.html

Linux进程间通信(IPC)由以下几部分发展而来:

1.      Unix进程间通信

2.      基于System V进程间通信

3.      POSIX进程间通信

分类

现在Linux使用的进程间通信方式包括:

1.      管道(pipe)和有名管道(FIFO)

2.      信号(signal)(事件通知)

3.      消息队列

4.      共享内存

5.      信号量

6.      套接字(socket)

管道通信

管道是单向的、先进先出的,它把一个进程的输出和另一个进程的输入连接在一起。一个进程(写进程)在管道的尾部写入数据,另一个进程(读进程)从管道的头部读出数据。

管道创建

管道包括无名管道和有名管道两种,前者用于父进程和子进程间的通信,后者可用于运行于同一系统中的任意两个进程间的通信。

无名管道有pipe()函数创建:

int pipe(int filedis[2]);

当一个管道建立时,它会创建两个文件描述符:filedis[0]用于读管道,filedis[1]用于写管道(将管道的头部和尾部分别看做两个文件,这两个文件就应该对应于两个文件描述符)

管道关闭

关闭管道只需将这两个文件描述符关闭即可,可以使用普通的close函数逐个关闭

管道读写

管道用于不同进程间通信。通常先创建一个管道,再通过fork函数创建一个子进程,该子进程会继承父进程所创建的管道(父进程和子进程通过该无名管道进行通信,父进程向该管道写数据,子进程向管道读数据)

注意事项

必须在系统调用fork()前调用pipe(),否则子进程将不会继承文件描述符(如果顺序相反,则会发现会创建两个管道)

例pipe_rw.c

命名管道(FIFO)

命名管道和无名管道基本相同,但也有不同点:无名管道只能由父子进程使用;但是通过命名管道,不相关的进程也能交换数据

从实质上来讲命名管道就是一个文件

创建

#include <sys/types.h>

#include <sys/stat.h>

int mkfifo(const char* pathname, mode_t mode)

--pathname:FIFO文件名(命名管道的名字)

--mode:属性(见文件操作章节)

一旦创建了一个FIFO,就可用open打开它,一般的文件访问函数(close、read、write等)都可用于FIFO

相关资料:http://my.oschina.net/renhc/blog/35125

http://blog.chinaunix.net/space.php?uid=20384806&do=blog&id=1954102

http://blog.chinaunix.net/uid-20384806-id-1954101.html

操作

当打开FIFO时,非阻塞标志(O_NONBLOCK)将对以后的读写产生如下影响:
1.没有使用O_NONBLOCK:访问要求无法满足时进程将阻塞。如试图读取空的FIFO,将导致进程阻塞

2.使用O_NONBLOCK:访问要求无法满足时不阻塞,立刻出错返回,errno是ENXIO

例fifo_write.c、fifo_read.c

信号通信

信号(signal)机制是Unix系统中最为古老的进程间通信机制,很多条件可以产生一个信号:

1.当用户按某些按键时,产生信号

2.硬件异常产生信号:除数为0、无效的存储访问等等。这些情况通常由硬件检测到,将其通知内核,然后内核产生适当的信号通知进程,例如,内核对正访问一个无效存储区的进程产生一个SIGSEGV信号

3.进程用kill函数将信号发送给另一个进程

4.用户可用kill命令将信号发送给其他进程

信号类型

下面是几种常见的信号:

SIGHUP:从终端发出的结束信号

SIGINT:来自键盘的中断信号(Ctrl-C)

SIGKILL:该信号结束接受信号的进程

SIGTERM:kill命令发出的信号

SIGCHLD:标示子进程停止或结束的信号

SIGSTOP:来自键盘(Ctrl-Z)或调试程序的停止执行信号

其他的信号类型baidu.com

信号处理

当某信号出现时,将按照下列三种方式中的一种进行处理:

1.忽略此信号

大多数信号都按照这种方式进行处理,但有两种信号决不能被忽略。他们是:SIGKILL和SIGSTOP。这两种信号不能被忽略的原因是:它们向超级用户提供了一种终止或停止进程的方法

2.执行用户希望的动作

通知内核在某种信号发生时,调用一个用户函数。在用户函数中,执行用户希望的处理

3.执行系统默认动作

对大多数信号的系统默认动作时终止该进程。

信号发送

发送信号的主要函数有kill和raise

区别:

kill既可以向进程本身发送信号,也可以向其他进程发送信号。Raise函数是向进程自身发送信号

#include <sys/types.h>

#include <signal.h>

int kill(pid_t pid, int signo)

---pid是要进行处理的进程ID

---sigo是要发出的信号类型

int raise(int signo)

kill的pid参数有四种不同的情况:

1.pid>0将信号发送给进程ID为pid的进程

2.Pid==0将信号发送给同组的进程

3.Pid<0将信号发送给其进程组ID等于pid绝对值的进程

4.Pid==-1将信号发送给所有进程。

Alarm

使用alarm函数可以设置一个时间值(闹钟时间),当所设置的时间到了时,产生SIGALRM信号(发送给自身)。如果不捕捉此信号,则默认动作是终止该进程。

#include <unistd.h>

unsigned int alarm(unsigned int seconds)

---seconds:经过了指定的seconds秒后会产生信号SIGALRM

每个进程只能有一个闹钟时间。如果在调用alarm时,以前已为该进程设置过闹钟时间,而且它还没有超时,以前登记的闹钟时间则被新值代换。

如果有以前登记的尚未超过的闹钟时间,而这次seconds值是0,则表示取消以前的闹钟

Pause

Pause函数使调用过程挂起直至捕捉到一个信号。

#include <unistd.h>

int pause(void)

只有执行了一个信号处理函数后,挂起才结束。

信号的处理

当系统捕捉到某个信号时,可以忽略该信号或是使用指定的处理函数来处理该信号,或者使用系统默认的方式

信号处理的主要方法有两种,一种是使用简单的signal函数,另一种是使用信号集函数组

Signal原型

#include <signal.h>

void (*signal (int signo, void(*func)(int)))(int)

如何理解?

typedef void (*sighandler_t)(int)

sighandler_t signal(int signum, sighandler_t handler)

第一个参数signum指明了所要处理的信号类型,它可以取除了SIGKILL和SIGSTOP外的任何一种信号。handler参数是一个指针,指向某个处理该信号的函数。这个处理信号函数带有一个int型参数,并应返回void。

func(handler)可能的值是:

1.SIG_IGN:忽略此信号

2.SIG_DFL:按系统默认方式处理

3.信号处理函数名:使用该函数处理.(所有的信号处理函数都只有一个int类型的参数)

例mysignal.c

参考资料:http://baike.baidu.com/view/64630.htm

共享内存

共享内存是被多个进程共享的一部分物理内存。共享内存是进程间共享数据的一种最快的方法,一个进程向共享内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容。

共享内存实现分为两个步骤:

一、创建共享内存,使用shmget函数

二、映射共享内存,将这段创建的共享内存映射到具体的进程空间去,使用shmat函数

创建

int shmget(key_t key, int size, int shmflg)

key标示共享内存的键值:0/IPC_PRIVATE。当key的取值为IPC_PRIVATE,则函数shmget()将创建一块新的共享内存;如果key的取值为0,而参数shmflg中又设置IPC_PRIVATE这个标志,则同样会创建一块新的共享内存

返回值:如果成功,返回共享内存标识符;如果失败,返回-1.

映射

void* shmat(int shmid, char* shmaddr, int flag)

参数:

---shmid:shmget函数返回的共享存储标识符

---flag:决定以什么方式来确定映射的地址(通常为0)

---shmaddr是指该共享内存在各进程中的地址值,如果是0则表示系统自动为其找一个地址址(同一块共享内存在各进程中是不一样的)

返回值:如果成功,则返回共享内存映射到进程中的地址;如果失败,则返回-1.

当一个进程不再需要共享内存时,需要把它从进程地址空间中脱离

int shmdt(char* shmaddr),其中shmaddr是从shmat()函数中的shmaddr中来

例shmem.c

1、 无名管道代码:#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <math.h>int main(int argc, char *argv[])
{pid_t pid;int pipe_fd[2];char buf_r[100];char *p_wbuf;int r_num;memset(buf_r, 0, sizeof(buf_r));if(pipe(pipe_fd) < 0){printf("pipe create error\n");return -1;}//create child processif((pid = fork()) == 0){printf("\n");close(pipe_fd[1]); sleep(2);if((r_num = read(pipe_fd[0], buf_r, 100)) > 0)printf("%d numbers read from the pipe is %s\n", r_num, buf_r);close(pipe_fd[0]);exit(0);}else if(pid > 0){close(pipe_fd[0]);if(write(pipe_fd[1], "Hello", 5) != -1)printf("parent write1 Hello\n");if(write(pipe_fd[1], "Pipe", 5) != -1)printf("parent write2 Pipe\n");close(pipe_fd[1]);waitpid(pid, NULL, 0);exit(0);}return 0;
}Makefile:CC = gccCURTDIR = $(shell pwd)
TARGET = mypipe%.o:%.c$(CC)-c $(EXTRAFLAGS) $< -o $@
%.o:%.S$(CC)-c $(EXTRAFLAGS) $< -o $@.PHONY: all clean$(TARGET): $(TARGET).o$(CC)  -o $@ $^clean:rm-rf $(TARGET) $(TARGET).o运行结果:eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.1$make
gcc -c mypipe.c -o mypipe.o
gcc -o mypipe mypipe.oeastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.1$ls
Makefile mypipe  mypipe.c  mypipe.oeastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.1$./mypipe
parent write1 Hello
parent write2 Pipe10 numbers read from the pipe is HelloPipe结论:由于fork函数让子进程完整地拷贝了父进程的整个地址空间,所以父子进程都有管道的读端和写端。而我们需要的是一个进程读,一个进程写,所以写的进程最好关闭读端,读的进程关闭写端。2、 有名管道代码1:#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <math.h>
#define FIFO_SERVER "/tmp/myfifo"int main(int argc, char *argv[])
{int fd;char w_buf[100];int nwrite;if((mkfifo(FIFO_SERVER, O_CREAT | O_EXCL | O_RDWR) < 0)&& (errno!= EEXIST))printf("cannot create fifoserver\n");fd = open(FIFO_SERVER, O_RDWR | O_NONBLOCK, 0);if(fd == -1){perror("open");exit(1);}if(argc == 1){printf("please send something\n");exit(-1);}strcpy(w_buf, argv[1]);if((nwrite == write(fd, w_buf, 100)) == -1){if(errno == EAGAIN)printf("The FIFO has not been read yet. please try later\n");}elseprintf("write %s to the FIFO\n", w_buf);close(fd);return 0;
}代码2:#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <math.h>
#define FIFO_SERVER "/tmp/myfifo"int main(int argc, char *argv[])
{int fd;char buf_r[100];int nread;if((mkfifo(FIFO_SERVER, O_CREAT | O_EXCL | O_RDWR) < 0)&& (errno!= EEXIST))printf("cannot create fifoserver\n");fd = open(FIFO_SERVER, O_RDWR | O_NONBLOCK, 0);if(fd == -1){perror("open");exit(1);}while(1){memset(buf_r, 0, sizeof(buf_r));if(nread = read(fd, buf_r, 100) == -1){if(errno == EAGAIN)printf("no datayet\n");}printf("read %s from FIFO\n", buf_r);sleep(1);}close(fd);pause();unlink(FIFO_SERVER);return 0;
}Makefile:CC = gccCURTDIR = $(shell pwd)
TARGET = myfifo_write
#TARGET = myfifo_read%.o:%.c$(CC)-c $(EXTRAFLAGS) $< -o $@
%.o:%.S$(CC)-c $(EXTRAFLAGS) $< -o $@.PHONY: all clean$(TARGET): $(TARGET).o$(CC)  -o $@ $^clean:rm-rf $(TARGET) $(TARGET).orm-rf $(TARGETR) $(TARGETR).o运行结果:eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.2$sudo ./myfifo_write hello
write hello to the FIFO
eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.2$sudo ./myfifo_write fifo
write fifo to the FIFOeastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.2$sudo ./myfifo_read
no data yet
read from FIFO
no data yet
read from FIFO
no data yet
read from FIFO
read hello from FIFO
no data yet
read from FIFO
read fifo from FIFO
no data yet
read from FIFO总结:先创建一个有名管道,打开管道之后向管道中写入由主函数传入的字符串,然后另一个进程循环从管道中读取数据。当没有数据时,是读不到的,当有数据时,就可以读到了。3、 信号处理代码:#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <math.h>
#include <signal.h>void my_func(int sign_no)
{if(sign_no == SIGBUS){printf("I have get SIGBUS\n");}
}int main(int argc, char *argv[])
{printf("Waiting for signal SIGBUS\n");signal(SIGBUS, my_func);pause();return 0;
}Makefile:CC = gccCURTDIR = $(shell pwd)
TARGET = mysig%.o:%.c$(CC)-c $(EXTRAFLAGS) $< -o $@
%.o:%.S$(CC)-c $(EXTRAFLAGS) $< -o $@.PHONY: all clean$(TARGET): $(TARGET).o$(CC)  -o $@ $^clean:rm-rf $(TARGET) $(TARGET).o运行结果:eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.3$make
gcc -c mysig.c -o mysig.o
gcc -o mysig mysig.oeastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.3$ls
Makefile mysig  mysig.c  mysig.oeastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.3$./mysig
Waiting for signal SIGBUSeastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.3$ps -aux | grep mysig
Warning: bad ps syntax, perhaps a bogus'-'? See http://procps.sf.net/faq.html
eastmoon 10270  0.0 0.4   9116  3124 pts/2   S+   15:09   0:00 vi mysig.txt
eastmoon 10295  0.0 0.0   1728   244 pts/3   S+   15:10   0:00 ./mysig
eastmoon 10300  0.0 0.1   5804   876 pts/4   S+   15:11   0:00 grep --color=auto mysig
eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.3$kill -BUS 10295eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.3$./mysig
Waiting for signal SIGBUS
I have get SIGBUS总结:signal系统调用为SIGBUS信号注册了信号处理函数,然后将进程挂起等待SIGBUS信号,当向该进程发送SIGBUS信号才会执行信号处理函数。4、 共享内存代码1:#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <errno.h>
#include <math.h>
#include <signal.h>
#include "shm_com.h"int main(int argc, char *argv[])
{int running = 1;void *shared_memory = (void*)0;struct shared_use_st *shared_stuff;int shmid;shmid = shmget((key_t)1234, sizeof(struct shared_use_st),0666|IPC_CREAT);if(shmid == -1){fprintf(stderr, "shmget failed\n");exit(EXIT_FAILURE);}shared_memory = shmat(shmid, (void*)0, 0);if(shared_memory == (void*)-1){fprintf(stderr, "shmmat failed\n");exit(EXIT_FAILURE);}printf("Memory attached at %x\n", (int)shared_memory);shared_stuff = (struct shared_use_st *)shared_memory;shared_stuff->written_by_you = 0;while(running){if(shared_stuff->written_by_you){printf("You wrote: %s\n", shared_stuff->some_text);sleep(1);shared_stuff->written_by_you = 0;if(strncmp(shared_stuff->some_text, "end", 3) == 0){running = 0;}}}if(shmdt(shared_memory) == -1){fprintf(stderr, "shmmdt failed\n");exit(EXIT_FAILURE);}return 0;
}代码2:#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <errno.h>
#include <math.h>
#include <signal.h>
#include "shm_com.h"int main(int argc, char *argv[])
{int running = 1;void *shared_memory = (void*)0;struct shared_use_st *shared_stuff;char buffer[BUFSIZ];int shmid;shmid = shmget((key_t)1234, sizeof(struct shared_use_st),0666|IPC_CREAT);if(shmid == -1){fprintf(stderr, "shmget failed\n");exit(EXIT_FAILURE);}shared_memory = shmat(shmid, (void*)0, 0);if(shared_memory == (void*)-1){fprintf(stderr, "shmmat failed\n");exit(EXIT_FAILURE);}printf("Memory attached at %x\n", (int)shared_memory);shared_stuff = (struct shared_use_st *)shared_memory;shared_stuff->written_by_you = 0;while(running){while(shared_stuff->written_by_you){sleep(1);printf("Waiting for client....\n");}printf("Enter some text: ");fgets(buffer, BUFSIZ, stdin);strncpy(shared_stuff->some_text, buffer, TEXT_SZ);shared_stuff->written_by_you = 1;if(strncmp(buffer, "end", 3) == 0){running = 0;}}if(shmdt(shared_memory) == -1){fprintf(stderr, "shmmdt failed\n");exit(EXIT_FAILURE);}return 0;
}代码3:#define TEXT_SZ 2048struct shared_use_st
{int written_by_you;char some_text[TEXT_SZ];
};Makefile:CC = gccCURTDIR = $(shell pwd)
#TARGET = myshm1
TARGET = myshm2%.o:%.c$(CC)-c $(EXTRAFLAGS) $< -o $@
%.o:%.S$(CC)-c $(EXTRAFLAGS) $< -o $@.PHONY: all clean$(TARGET): $(TARGET).o$(CC)  -o $@ $^clean:rm-rf $(TARGET) $(TARGET).o运行结果:eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.4$make
gcc -c myshm1.c -o myshm1.o
gcc -o myshm1 myshm1.o
eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.4$ls
Makefile myshm1  myshm1.c  myshm1.o myshm2.c  shm_com.heastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.4$make
gcc -c myshm2.c -o myshm2.o
gcc -o myshm2 myshm2.o
eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.4$ls
Makefile myshm1  myshm1.c  myshm1.o myshm2  myshm2.c  myshm2.o shm_com.heastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.4$./myshm1
Memory attached at b78db000eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.4$./myshm2
Memory attached at b7731000
Enter some text: my first share memory
Waiting for client....
Waiting for client....
Enter some text: it's so good
Waiting for client....
Waiting for client....
Enter some text: ok, now let's study otherthings.
Waiting for client....
Waiting for client....
Enter some text: end    eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.4$./myshm1
Memory attached at b78db000
You wrote: my first share memoryYou wrote: it's so goodYou wrote: ok, now let's study otherthings.You wrote: end总结:用于通信的两个进程必须用同一块共享内存进行通信,所以shmget的第一个参数key必须是相同的。5、 消息队列代码1:#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <math.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/msg.h>struct my_msg_st
{long int my_msg_type;char some_text[BUFSIZ];
};int main(int argc, char *argv[])
{int running = 1;int msgid;struct my_msg_st some_data;long int msg_to_receive = 0;msgid = msgget((key_t)2222, 0666 | IPC_CREAT);if(msgid == -1){fprintf(stderr, "msgget failed with error: %d\n", errno);exit(EXIT_FAILURE);}while(running){if(msgrcv(msgid, (void*)&some_data, BUFSIZ, msg_to_receive, 0) ==-1){fprintf(stderr, "msgrcv failed with error: %d\n", errno);exit(EXIT_FAILURE);}printf("You wrote: %s\n", some_data.some_text);if(strncmp(some_data.some_text, "end", 3) == 0){running = 0;}}       if(msgctl(msgid, IPC_RMID, 0) == -1){fprintf(stderr, "msgctl failed with error: %d\n", errno);exit(EXIT_FAILURE);}return 0;
}代码2:#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <math.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/msg.h>struct my_msg_st
{long int my_msg_type;char some_text[BUFSIZ];
};int main(int argc, char *argv[])
{int running = 1;int msgid;struct my_msg_st some_data;char buffer[BUFSIZ];msgid= msgget((key_t)2222, 0666 | IPC_CREAT);if(msgid == -1){fprintf(stderr, "msgget failed with error: %d\n", errno);exit(EXIT_FAILURE);}while(running){printf("Enter some text:");fgets(buffer, BUFSIZ, stdin);some_data.my_msg_type = 1;strcpy(some_data.some_text, buffer);if(msgsnd(msgid, (void*)&some_data, BUFSIZ, 0) == -1){fprintf(stderr, "msgsnd failed with error: %d\n", errno);exit(EXIT_FAILURE);}if(strncmp(some_data.some_text, "end", 3) == 0){running = 0;}}return 0;
}Makefile:CC = gccCURTDIR = $(shell pwd)
TARGET = mymsg1
#TARGET = mymsg2%.o:%.c$(CC)-c $(EXTRAFLAGS) $< -o $@
%.o:%.S$(CC)-c $(EXTRAFLAGS) $< -o $@.PHONY: all clean$(TARGET): $(TARGET).o$(CC)  -o $@ $^clean:rm-rf $(TARGET) $(TARGET).o运行结果:eastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.5$make
gcc -c mymsg1.c -o mymsg1.o
gcc -o mymsg1 mymsg1.oeastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.5$ls
Makefile mymsg1  mymsg1.c  mymsg1.oeastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.5$make
gcc -c mymsg2.c -o mymsg2.o
gcc -o mymsg2 mymsg2.oeastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.5$ls
Makefile mymsg1  mymsg1.c  mymsg1.o mymsg2  mymsg2.c  mymsg2.oeastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.5$./mymsg2
Enter some text:hello
Enter some text:mymsg
Enter some text:good-buy
Enter some text:endeastmoon@eastmoon-virtual-machine:~/work/guoqian/2/2.5$./mymsg1
You wrote: helloYou wrote: mymsgYou wrote: good-buyYou wrote: end总结:在没有运行msg2向消息队列中添加消息的时候,msg1会阻塞在msgrcv函数上,运行msg2后,每添加一条消息,msg1就读取一条,直到添加的消息为”end”,结束。

linux 进程间通信及makefile 无名管道/有名管道/共享内存/信号/消息队列相关推荐

  1. Linux下进程间通信方式之管道、信号、共享内存、消息队列、信号量、套接字

    /* 1,进程间通信 (IPC ) Inter-Process Communication比较好理解概念的就是进程间通信就是在不同进程之间传播或交换信息.2,linux下IPC机制的分类:管道.信号. ...

  2. VxWorks中的任务间通信(信号量、共享内存、消息队列、管道、信号、事件、套接字socket)

    文章目录 信号量 共享内存 消息队列 管道 信号 事件 套接字(socket) 总结 VxWorks5.5中,为了保证各个独立的任务可以协同工作,提供了一整套任务间的通信机制,主要包括信号量,共享内存 ...

  3. 【Linux Program】信号量、共享内存和消息队列

    系列文章: 文件操作 数据管理 进程和信号 POSIX 线程 进程间通信:管道 信号量共享内存和消息队列 套接字 文章目录 1. 信号量 1.1 信号量的定义 1.2 Linux 的信号量机制 1.3 ...

  4. 《linux程序设计》--读书笔记--第十四章信号量、共享内存和消息队列

    信号量:用于管理对资源的访问: 共享内存:用于在程序之间高效的共享数据: 消息队列:在程序之间传递数据的一种简单方法: 一.信号量 临界代码:需要确保只有一个进程或者一个执行线程可以进入这个临界代码并 ...

  5. Linux 进程间通信:管道、共享内存、消息队列、信号量

    进程间通信 管道 共享内存 消息队列 信号量 进程间通信 https://blog.csdn.net/qq_35423154/article/details/105294963 在之前的一篇博客中讲过 ...

  6. linux进程间通信快速入门【二】:共享内存编程(mmap、XSI、POSIX)

    文章目录 mmap内存共享映射 XSI共享内存 POSIX共享内存 参考 使用文件或管道进行进程间通信会有很多局限性,比如效率问题以及数据处理使用文件描述符而不如内存地址访问方便,于是多个进程以共享内 ...

  7. 【Linux篇】第十二篇——进程间通信(管道+system V共享内存)

    进程间通信介绍 概念 目的 本质 分类 管道 什么是管道 匿名管道 匿名管道的原理 pipe函数 匿名管道使用步骤 管道读写规则 管道的特点 管道的大小 命名管道 命名管道的原理 使用命令创建命名管道 ...

  8. Linux C 进程间的IPC通信 之 共享内存(一)

    1.IPC(inter - process communication)通信 共享内存.消息队列.信号灯 2.库 <sys/shm.h> 2-1  创建共享内存 int shmget( k ...

  9. win32下进程间通信方式之管道、邮件槽、剪切板、共享内存、消息、套接字、RPC、DDE等

    #include "stdafx.h"/*32位Windows采用虚拟内存技术使每个进程虚拟4G内存,在逻辑上实现了对进程之间数据代码的分离与保护.那么相应的进程之间的通信也就有必 ...

最新文章

  1. 【Linux系统】基础总结
  2. java emailbuilder 样式_Java8通用Builder了解一下
  3. 我和学员那些事儿——涅槃重生的背后
  4. 代码管理工具 Git
  5. 微信扫描二维码和浏览器扫描二维码 ios和Android 分别进入不用的提示页面
  6. 第七篇:Spring Boot整合Thymeleaf_入门试炼03
  7. mplayer-php,mplayer+smplayer 前后端播放器安装
  8. .sh文件怎么写_typeScript 配置文件该怎么写?
  9. 【英语学习】【Daily English】U02 Daily Routine L02 I go to the gym every other day
  10. AndroidStudio断点调试
  11. memcached高速缓存学习笔记002---telnet操作memcached
  12. IOS开发UI控件UIScrollView和Delegate的使用
  13. 【报告分享】“流量重构”时代来临,2020-2021中国消费互联网竞争趋势报告-腾讯.pdf(附下载链接)...
  14. 解决 此 Flash Player 与您的地区不相容 问题
  15. CommandName 与 CommandArgument
  16. 常见Dos攻击原理及防护(死亡之Ping、Smurf、Teardown、LandAttack、SYN Flood)
  17. -2. JavaScript Methods
  18. Endnote导入中文文献格式
  19. 征服游戏 Floyd算法
  20. python控制鼠标移动

热门文章

  1. android usb 检测工具,Android:如何检测已连接的USB设备?
  2. 读书笔记——物联网导论第3版(1)
  3. 连载一来到无限互联的心得
  4. lxml.html方法,用lxml编辑html代码
  5. caffe2的安装与遇到的问题和解决问题步骤
  6. JavaScript标签选取
  7. 超级详细的PostgreSQL创建数据库操作并附带图文
  8. LeetCode第111题解析
  9. 计算机毕业设计Java校园食堂订餐系统(源码+系统+mysql数据库+Lw文档)
  10. 提高LCD屏幕刷新效率