Interprocess communication 2020-12-28

 

Application scenarios of interprocess communication: data transmission, shared data, notification events, resource sharing, and process control
Communication between processes of the same host:
unix interprocess communication mode: famous pipeline, nameless pipeline and signal.
system V interprocess communication mode and POSIX interprocess communication mode are
Message queue, shared memory, semaphore.
Inter process communication between different hosts (networks): Socket


Nameless pipe: pipe creation {fork creation sub process
It can only be used for communication between blood related processes
The life cycle follows the process, the process exits, and the pipeline is released
The pipeline is half duplex, and data can only be transmitted from one direction
The pipeline is based on byte stream
The pipeline has its own synchronization mechanism. On the premise of ensuring data security, it accesses critical resources in a specific order

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h> //exit

int main ()
{
	int fds[2];
	pipe(fds);

	pid_t pid = fork();
	if(pid == 0)//child
	{
		char buf[10] = {0};
		read(fds[0], buf, sizeof(buf));
		printf("child read= %s\n", buf);
		exit(0);

	}else if(pid > 0)//parent
	{
		write(fds[1], "hello", 5);
		wait(NULL);//
		exit(0);
	}else
	{
		perror("fork error\n");
		exit(1);
	}

}


Famous pipeline: mkfifo create pipeline access judge whether the file exists read write
It is a half duplex communication mode, but allows unrelated inter process communication
A named pipe is a special type of file that is basically similar to an anonymous pipe

//read.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>//pipe
#include <stdlib.h>//exit

//mkfifo  tmp
//Read before write
int main ()
{
	int fd = open("tmp", O_RDWR);
	if(fd < 0)
	{
		perror("open error\n");
		exit(1);
	}
	
	char buf[10] = {0};
	read(fd, buf, sizeof(buf));
	printf("read buf =%s\n", buf);

	close(fd);

	return 0;

}

//write.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>//pipe
#include <stdlib.h>//exit

int main ()
{
	int fd = open("tmp", O_RDWR);
	if(fd < 0)
	{
		perror("open error\n");
		exit(1);
	}

	write(fd, "hello", 5);
	close(fd);

	return 0;

}

Message queue:

Message queue is a linked list of messages, which is stored in the kernel and represented by the message queue identifier.
Features: the life cycle varies with the kernel, and the message queue will always exist. We need to delete the calling interface displayed or use the command to delete it
Message queuing allows two-way communication
It overcomes the disadvantage that the pipeline can only carry unformatted byte stream

ipcs: display IPC resources
ipcrm: manually delete IPC resources

msgtype > 0
Receive messages with message type msgtype
msgtype==0
Receive the first message in the message queue
msgtype<0
Example-5 (can read one to four of the absolute value | - 5)

//read
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/msg.h>
//read.c -o read
//write.c  -o write 
//ipcs exist here
struct msgbuf
{
	long mtype;
	char mtext[100];
};
int main ()
{
	int id = msgget(0x123456, IPC_CREAT | IPC_PRIVATE);

	struct msgbuf buf;
		
	msgrcv(id, &buf, sizeof(buf), 10, IPC_NOWAIT);
	printf("buf.mtype =%d, buf.mtext= %s\n", buf.mtype, buf.mtext);

	return 0;
}
//write
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/msg.h>
#include <string.h>

struct msgbuf
{
	long mtype;
	char mtxt[100];
};

int main ()
{
	int id = msgget(0x123456, IPC_PRIVATE);

	struct msgbuf buf;
	buf.mtype = 10;
	strcpy(buf.mtxt, "hello");

	msgsnd(id, &buf, sizeof(buf), IPC_NOWAIT);


	return 0;
}


Shared memory:
In a computer system with multiple processors, a large amount of space that can be accessed by different CPU s. That is, a piece of physical memory is mapped to the address space of two processes, and both processes can access this space to realize inter process communication
characteristic:
Shared memory is the fastest form of IPC. Because the memory is mapped to the address space of the processes sharing it, the data transmission of these processes will no longer involve the kernel, that is to say, it will no longer be used to transmit each other's data through the execution of system calls into the kernel. Therefore, its speed is the fastest.
The life cycle of shared memory also needs to be deleted explicitly with the process.
Shared memory has no mutual exclusion and synchronization mechanism, so we need to add it ourselves when using it.

//read
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/ipc.h>

int main ()
{
	int id = shmget(0x8989, 4096, IPC_PRIVATE | IPC_CREAT);

	char *p = shmat(id, NULL, 0);
	printf("p= %s\n", p);

	shmdt(p);//Unmap

	return 0;
}
//write
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <string.h>

int main ()
{
	int id = shmget(0x8989, 4096, IPC_PRIVATE | IPC_CREAT);

	char *p = shmat(id, NULL, 0);
	strcpy(p, "aaaa");
	shmdt(p);//Unmap

	return 0;
}

Signal:

It is a complex communication method used to notify the receiving process that an event has occurred
Press CTRL +c CTRL + z
System call kill raise abort
Software condition generates alarm
Hardware exception segment error
You can use the kill -l command to view the list of signals in Linux.

#include <stdio.h>
#include <signal.h>

//pkill + filename kill file
//kill + number + process number

void handler(int signum)
{
	printf("signum = %d\n", signum);

}

int main ()
{
	signal(SIGINT, handler);
//	signal(SIGINT, SIG_IGN);// Ignore signal
//	signal(SIGINT, SIG_DFL);// Default signal
//	signal(SIGKILL, SIG_DFL);// 	 Sigkill sigstop / / cannot be captured or ignored
	
//	Sigkill sigstop / / cannot be captured or ignored
	while(1);
	return 0;
}

 

Added by mjm7867 on Tue, 08 Feb 2022 11:57:14 +0200