1
0
SWNote/Linux/Linux_IPC.md
2021-08-08 23:15:06 +08:00

10 KiB
Executable File
Raw Permalink Blame History

Linux Process Introduction

IPC ( Inter-Process Communication) , the Software Program is image for machine code and data which is stored in disks and can be executed it is a passive static entity, but the Process is program which executing under CPU, can apply and own the system resource . contain the program and info of current activity it is a dynamic entity.

The ways for Linux IPCs such like Signal , Pipe /FIFO , Message queue , Semaphore, Share Memory ect. more detail check the following url.

ipc1

ipc2

Signal

Signals are a limited form of inter-process communication (IPC), typically used in Unix, Unix-like, and other POSIX-compliant operating systems. A signal is an asynchronous notification sent to a process or to a specific thread within the same process in order to notify it of an event that occurred.

When a signal is sent, the operating system interrupts the target process' normal flow of execution to deliver the signal. Execution can be interrupted during any non-atomic instruction. If the process has previously registered a signal handler, that routine is executed. Otherwise, the default signal handler is executed.

Embedded programs may find signals useful for inter-process communications, as the computational and memory footprint for signals is small.

Signals are similar to interrupts, the difference being that interrupts are mediated by the processor and handled by the kernel while signals are mediated by the kernel (possibly via system calls) and handled by processes. The kernel may pass an interrupt as a signal to the process that caused it (typical examples are SIGSEGV, SIGBUS, SIGILL and SIGFPE).

Each signal has a current disposition, which determines how the process behaves when it is delivered the signal.

( Note: 信号是Unix/Linux系统在一定条件下生成的事件。信号是一种异步通信机制进程不需要执行任何操作来等待信号的到达。信号异步通知接收信号的进程发生了某个事件然后操作系统将会中断接收到信号的进程的执行转而去执行相应的信号处理程序。)

#include <signal.h> 
void (*signal (int, void (*)(int)))(int);

typedef void (*sighandler_t)(int);
/*如果signal()调用成功返回最后一次为安装信号signum而调用signal()时的handler值
失败则返回SIG_ERR。*/
sighandler_t signal(int signum, sighandler_t handler);
/* sigaction函数用于改变进程接收到特定信号后的行为。*/
int sigaction(int signum, const struct sigaction* act, struct sigaction* oldact);
int kill(pid_t pid, int sig);
int sigqueue(pid_t pid, int sig, const union sigval value);

Sending Signals

#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;
    sig=atoi(argv[1]);
    sigemptyset(&act.sa_mask);
    act.sa_flags=SA_SIGINFO;
    act.sa_sigaction=new_op;
    
    if(sigaction(sig,&act,NULL) < 0) {
        printf("install sigal error\n");
    }   
    
    while(1) {
        sleep(2);
        printf("wait for the signal\n");
    }   
}   

void new_op(int signum,siginfo_t *info,void *myact) {
    printf("receive signal %d", signum);
    sleep(5);

}

Note:

SIGABRT 6 Terminate (core dump) Process abort signal
SIGALRM 14 Terminate Alarm clock
SIGBUS N/A Terminate (core dump) Access to an undefined portion of a memory object
SIGCHLD N/A Ignore Child process terminated, stopped, or continued
SIGCONT N/A Continue Continue executing, if stopped
SIGFPE N/A Terminate (core dump) Erroneous arithmetic operation
SIGHUP 1 Terminate Hangup
SIGILL N/A Terminate (core dump) Illegal instruction
SIGINT 2 Terminate Terminal interrupt signal
SIGKILL 9 Terminate Kill (cannot be caught or ignored)
SIGPIPE N/A Terminate Write on a pipe with no one to read it
SIGPOLL N/A Terminate Pollable event
SIGPROF N/A Terminate Profiling timer expired
SIGQUIT 3 Terminate (core dump) Terminal quit signal
SIGSEGV N/A Terminate (core dump) Invalid memory reference
SIGSTOP N/A Stop Stop executing (cannot be caught or ignored)
SIGSYS N/A Terminate (core dump) Bad system call
SIGTERM 15 Terminate Termination signal
SIGTRAP 5 Terminate (core dump) Trace/breakpoint trap
SIGTSTP N/A Stop Terminal stop signal
SIGTTIN N/A Stop Background process attempting read
SIGTTOU N/A Stop Background process attempting write
SIGUSR1 N/A Terminate User-defined signal 1
SIGUSR2 N/A Terminate User-defined signal 2
SIGURG N/A Ignore High bandwidth data is available at a socket
SIGVTALRM N/A Terminate Virtual timer expired
SIGXCPU N/A Terminate (core dump) CPU time limit exceeded
SIGXFSZ N/A Terminate (core dump) File size limit exceeded
SIGWINCH N/A Ignore Terminal window size changed

Handle Signals

Pipe

The pipe in Linux is identical in concept to the pipe in Unix, and is a core element of the Unix philosophy. The core idea that relates to pipes is you can pipeline simple Apps together and create a complex operation using pipes instead of needing large, complex applications.

(Note: 父进程和子进程之间或者两个兄弟进程之间可以通过系统调用建立起一个单向的通信管道。但是这种管道只能由父进程开建立对于子进程来说是静态的与生俱来的。管道两端的进程各自都将该管道视作一个文件。一个进程写另一个进程读。并且通过管道传递的内容遵循“先入先出”FIFO的原则。每个管道都是单向的需要双向通信时就要建立两个管道。)

1. Pipe == byte stream buffer in kernel

  • Sequential (cant lseek())

  • Multiple readers/writers difficult

2. Unidirectional

  • Write end + read end
ls | wc -l

ipc_pipe

/*
filedes[0]: used only for read
filedes[1]: used only for write
*/
int filedes[1];
int pipe(int filedes[1]);
write(filedes[1], buf, count);
read(filedes[0], buf, count);
Close();
Sample:
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
main() {
	int pipe_fd[2];
	pid_t pid;
	char r_buf[100];
	char w_buf[4];
	char* p_wbuf;
	int r_num;
	int cmd;
	
	memset(r_buf,0,sizeof(r_buf));
	memset(w_buf,0,sizeof(r_buf));
	p_wbuf=w_buf;
	if(pipe(pipe_fd)<0)
	{
		printf("pipe create error\n");
		return -1;
	}
	
	if((pid=fork())==0)
	{
	    printf("\n");
	   close(pipe_fd[1]);
                       sleep(3);//确保父进程关闭写端
	    r_num=read(pipe_fd[0],r_buf,100);
                       printf("read num is %d   the data read from the pipe is %d\n",r_num,atoi(r_buf));

                       close(pipe_fd[0]);
	    exit();
	}
	else if(pid>0)
	{
	close(pipe_fd[0]);//read
	strcpy(w_buf,"111");
	if(write(pipe_fd[1],w_buf,4)!=-1)
		printf("parent write over\n");
	close(pipe_fd[1]);//write
		printf("parent close fd[1] over\n");
	sleep(10);
	}	
}

FIFO (named pipe)

  • pipes (anonymous) can only be used by related processes

  • FIFOs == pipe with name in file system

  • Creation:

      mkfifo(pathname, permissions)
    
  • Any process can open and use FIFO

  • I/O is same as for pipes

open(pathname, O_WRONLY/O_RDONLY);
#Open write/read end
open();
# locks until other end is opened Opens are synchronized
open(pathname, O_RDONLY | O_NONBLOCK);
# can be useful

Sample


Message Queue

# Queue management (analogous to files)
# open/create MQ, set attributes
# flags (analogous to open()):
# 	O_CREAT  create MQ if it doesnt exist
#	O_EXCL  create MQ exclusively
#	O_RDONLY, O_WRONLY, O_RDWR  just like file open
#	O_NONBLOCK  non-blocking I/O
# mode sets permissions
# &attr: attributes for new MQ
#	NULL gives defaults
mqd = mq_open(name, flags [, mode, &attr]);
# close MQ
mq_close();
# remove MQ pathname
mq_unlink();

# I/O
# send message
mq_send();
# receive message
mq_receive();

# Other:
# set/get MQ attributes
mq_setattr(); / mq_getattr(); 
# request notification of msg arrival
mq_notify();


Sample:


Socket

Semaphore

Shared Memory