1、pipe
1)只能用于具有亲缘关系的进程间通信
2)半双工通信,具有相同的读写端
#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { int pfd[2]; int pid; int data = 23; //create pipe if(pipe(pfd) < 0) { //failed perror(" create pipe failed !\n"); return -1; } else { if((pid = fork()) < 0) { perror("create process failed !\n"); } else if(pid > 0) { //parent process close(pfd[0]); write(pfd[1],&data, sizeof(int)); close(pfd[1]); } else { //child process close(pfd[1]); read(pfd[0],&data,10); close(pfd[0]); } } }
内核实现步骤总结:
1. 初始化管道文件系统
2. 注册和加载文件系统
3. 建立write,read管道,返回文件以及文件描述符
4. 写和读
5. close
======================
do_pipe_flag
create_write_pipe
get_pipe_info
alloc_pipe_info
create_read_pipe
get_unused)fd_flags
fd_install
======================
2、fifo
mkfifo(const char *pathname,mode_t mode);
read例程:
#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define FIFO_PATH "my_fifo_file" //read fifo int main(void) { int fd; char cont[255]; //create fifo file if(mkfifo(FIFO_PATH,0666) < 0 && error != EEXIST) { perror("create fifo failed !\n"); return -1; } else { printf("create fifo success !\n"); //open file fd = open(FIFO_PATH,O_CREATE|O_RDONLY,0666); if(fd >0) { //read cont while(1) { read(fd,cont,255); printf("read : %s !\n",cont); } close(fd); } else { perror("open failed !\n"); } return 0; } }
write例程:
#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define FIFO_PATH "my_fifo_file" //read fifo int main(void) { int fd; char cont[] = " hello test"; //create fifo file if(mkfifo(FIFO_PATH,0666) < 0 && error != EEXIST) { perror("create fifo failed !\n"); return -1; } else { printf("create fifo success !\n"); //open file fd = open(FIFO_PATH,O_CREATE|O_RDONLY,0666); if(fd >0) { //read cont while(1) { write(fd,cont,strlen(cont)); printf("write success !\n"); } close(fd); } else { perror("open failed !\n"); } return 0; } }
3、 siginal
1. 软中断信号:用来通知进程发生了异步事件。进程之间可以互相通过系统调用kill发送软中断信号。内核也可以因为内部事件而给进程发送信号,通知进程发生了某个事件。
2. 信号只是用来通知进程发生了什么事件,并不给该进程传递任何数据。
//发送信号
1)想进程本身发送信号
int raise(int SIGNO);
2)向指定进程发送信号
int kill(pid_t pid,int SIGNO)
3) 特殊发送信号函数,比如:
unsigned int alarm(unsigned int seconds);
4) 等待信号
pause()
5) 内核代码跟踪
do_tkill
do_sned_soecific
do_send_sig_info
send_signal
__send_signal
typedef void (*sighandler_t)(int); sighandler_t signal(int signum,sighandler_t handler); /********************************/ #include <stdio.h> #include <signal.h> #include <unistd.h> void sig_handler(int sig_no) { if(sig_no == SIGINT) { printf(" get sigint !\n"); } else if(sig_no == SIGQUIT) { printf("get SIGQUIT !\n"); } } int main() { printf("waiting for signal !\n"); //register signal signal(SIGINT,sig_handler); signal(SIGQUIT,sig_handler); pause(); }
4、共享内存
write例程:
#include <sys/ipc.h> #include <sys/shm.h> #include <sys/types.h> #include <string.h> #include <stdio.h> int main(void) { void *shm_addr; int shmid; char cont[] = "hello test"; //1. create share memory shmid = shmget(12345,2048,IPC_CREATE|0666); if(shmid != -1) { //2. map address shm_addr = shmat(shmid,NULL,0); if(share_memory != (void *)-1) { //copy mem memcpy(shm_addr,cont,sizeof(cont)); printf("save success !\n"); shmdt(shm_addr); } else { perror("shmat:"); } } else { perror("shmget"); } return 0; }
read例程:
#include <sys/ipc.h> #include <sys/shm.h> #include <sys/types.h> #include <string.h> #include <stdio.h> int main(void) { void *shm_addr; int shmid; char cont[] = "hello test"; //1. create share memory shmid = shmget(12345,2048,IPC_CREATE|0666); if(shmid != -1) { //2. map address shm_addr = shmat(shmid,NULL,0); if(share_memory != (void *)-1) { printf("get data = %s !\n",(char *)shm_addr); shmdt(shm_addr); } else { perror("shmat:"); } } else { perror("shmget"); } return 0; }
5 消息队列
1、数据读一遍数据之后,数据就不存在了(消息被取走之后就不存在了)
2、默认的配置会导致阻塞,可以在recv 和snd 函数中设置NOWAIT
send例程:
#include <sys/ipc.h> #include <sys/msg.h> #include <sys/types.h> #include <string.h> #include <stdio.h> struct magbuf { long mtype; char ntext[255]; }; int main() { struct msgbuf mybuf; int msggid = 0; mybuf.mtype = 1; strcpy(mybuf.ntext,"hello test"); //1. create message queue msggid = msgget(2345,IPC_CREATE|0666); if(msggid == -1) { //2. send message queue if(msgsnd(msggid,&mybuf,sizeof(mybuf.ntext),0)!= -1) { printf("sned message success !\n"); } else { perror(" send error !\n"); } } else { perror("msgget error !\n"); } return 0; }
recv例程:
#include <sys/ipc.h> #include <sys/msg.h> #include <sys/types.h> #include <string.h> #include <stdio.h> struct magbuf { long mtype; char ntext[255]; }; int main() { struct msgbuf mybuf; int msggid = 0; //1. create message queue msggid = msgget(2345,IPC_CREATE|0666); if(msggid == -1) { //2. send message queue if(msgrecv(msggid,&mybuf,sizeof(mybuf.ntext),1,0)!= -1) { printf("recv message success ; %s !\n",mybuf.ntext); //3. delete queue if(msgctl(msggid,IPC_RMID,0) != -1) { printf(" delete queeu success !\n"); } } else { perror(" recv error !\n"); } } else { perror("msgget error !\n"); } return 0; }
6、信号量 semphore
操作流程:
1. 建立信号量
2. 操作信号量
3. lock unlock
#include <sys/ipc.h> #include <sys/sem.h> #include <sys/types.h> #include <string.h> #include <stdio.h> int semid = 0; struct sembuf sem_down = {0,-1,0}; struct sembuf sem_up = (0,1,0); void down() { semop(semid,&sem_down,1); } void up() { semop(semid,&sem_up,1); } int main() { //1. create sem semid = semget(2345.1,IPC_CREATE|0666); if(semid != -1) { //2. set semaphore = 1 semctl(semid,1,SETVAL); //3. locl unlock down(); // lock printf(" hello test !\n"); up(); // unlock } else { perror("semget error !\n"); } return 0; }
7、
7) socket
//socket 常用函数
socket -- create an endpoint for communication
int socket(int domain,int type,int protocol);
bind -- bind a name to a socket
int bind(int sockfd,const struct sockaddr *addr, socklen_t addrlen);
listen -- listen for connections on a socket
int listen(int sockfd,int backlog);
accept -- accept a connections on a socket
int accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen);
read ,write ,close
send,sendto ,sendmsg -- send a message to a socket
ssize_t send(int sockfd,const coid *buf,size_t len,int flags);
ssize_t snedto(int sockfd,const void *buf,size_t len,int flags,const struct sockaddr *dest_addr,socklen_t addrlen);
ssize_t sendmsg(int sockfd,const struct msghdr *msg,int flags);
recv,recvfrom,recvmsg -- receive a message from a socket
server例程:
#include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #include <string.h> //server.c int main() { int server_fd; int client_fd; struct sockaddr_un myaddr; struct sockaddr_un client_addr; myaddr.sun_family = AF_UNIX; strcpy(myaddr.sun_path,"testsockfile"); int client_addr_len = sizeof(client_addr); //1.socket server_fd = socket(AF_UNIX,SOCK_STREAM,0); if(serverfd == -1) { printf("socket error !\n"); exit(1); } // 2.bind if(bind(serverfd,(struct sockaddr *)&myaddr,sizeof(myaddr)) == -1) { perror("bind error !\n"); exit(1); } // 3. listen if(listen(server_fd,20 ) == -1) // 20 times { perror("listen error !\n"); exit(1); } // 4. accept client_fd = accept(server_fd,(struct sockaddr *)&client_addr,&client_addr_len); if(client_fd == -1) { perror("accept error !\n"); exit(1); } // 5. op write(client_fd,"hello test",10); // 6. close close(client_fd); close(server_fd); return 0; }
client例程:
#include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #include <string.h> //client.c int main() { int server_fd; int client_fd; char buf[100]; struct sockaddr_un myaddr; struct sockaddr_un client_addr; myaddr.sun_family = AF_UNIX; strcpy(myaddr.sun_path,"testsockfile"); int client_addr_len = sizeof(client_addr); //1.socket server_fd = socket(AF_UNIX,SOCK_STREAM,0); if(serverfd == -1) { printf("socket error !\n"); exit(1); } //2.connect if(connect(serverfd,(struct sockaddr *)&myaddr,sizeof(myaddr)) == -1) { perror("connect error !\n"); exit(1); } // 3. op read(serverfd,buf,100); printf(" get server data = %s !\n",buf); // 6. close close(server_fd); return 0; }