天天看点

linux 几种IPC例子总结

1.管道

1.1普通管道

#include <unistd.h>

#include <sys/types.h>

#include <stdio.h>

#include <errno.h>

#include <stdlib.h>

int main()

{

       int pipe_fd[2];

       pid_t pid;

       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;

       }

       if((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 write surcess/n");

              if(write(pipe_fd[1], "pipe", 5) != -1)

                     printf("parent write success/n");

              close(pipe_fd[1]);

              sleep(2);

              waitpid(pid, NULL, 0);

              exit(0);

       }

}

1.2 基于文件流管理

#include <unistd.h>

#include <sys/types.h>

#include <errno.h>

#include <stdio.h>

#include <stdlib.h>

#define BUFSIZE 1024

int main()

{

       FILE *fp;

       char *cmd = "ps -ef";

       char buf[BUFSIZE];

       buf[BUFSIZE] = '/0';

       if((fp = popen(cmd, "r")) == NULL)

              perror("popen");

       while((fgets(buf, BUFSIZE, fp)) != NULL)

              printf("%s", buf);

       pclose(fp);

       exit(0);

}

1.3命名管道

#include <sys/types.h>

#include <sys/stat.h>

#include <unistd.h>

#include <fcntl.h>

#include <errno.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define FIFO "/tmp/myfifo"

int

main(int argc, char **argv)

{

       char buf_r[100];

       int fd;

       int nread;

       if((mkfifo(FIFO, O_CREAT | O_EXCL) < 0) && (errno != EEXIST))

              printf("cannot create fifoserver/n");

       printf("Preparing for reading bytes../n");

       memset(buf_r, 0 , sizeof(buf_r));

       fd = open(FIFO, O_RDONLY | O_NONBLOCK, 0);

       if(fd == -1)

       {

              perror("open FIFO failed!/n");

              exit(1);

       }

       while(1)

       {

              memset(buf_r, 0, sizeof(buf_r));

              if((nread = read(fd, buf_r, 100)) == -1)

              {

                     if(errno == EAGAIN)

                            printf("no data yet]n");

              }

              printf("read %s, from FIFO/n", buf_r);

              sleep(1);

       }

       pause();

       unlink(FIFO);

}

#include <unistd.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <errno.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define FIFO_SERVER   "/tmp/myfifo"

int

main(int argc, char ** argv)

{

       int fd;

       char w_buf[100];

       int nwrite;

       fd = open(FIFO_SERVER, O_WRONLY | O_NONBLOCK, 0);

       if(fd == -1)

       {

              if(errno == ENXIO)

                     printf("open error, no reading process/n");

       }

       if(argc == 1)

              printf("Please send something/n");

       strcpy(w_buf, argv[1]);

       if((nwrite = write(fd, w_buf, 100)) == -1)

       {

              if(errno == EAGAIN)

                            printf("no data yet/n");

    }

       else

              printf("write %d characters: %s/n", nwrite, w_buf);

}

信号及信号集

#include <signal.h>

#include <stdio.h>

#include <stdlib.h>

void my_func(int sig_no)

{

       if(sig_no == SIGINT)

              printf("I have get SIGINT/n");

       else if(sig_no == SIGQUIT)

              printf("I have get SIGQUIT/n");

}

int main()

{

       printf("Waiting for signal SIGINT or SIGQUIT/n");

       signal(SIGINT, my_func);

       signal(SIGQUIT, my_func);

       pause();

       exit(0);

}

2. 信号集

#include <stdio.h>

#include <stdlib.h>

#include <signal.h>

void my_func(int signum)

{

       printf("If you want to quit, please try SIGQUIT/n");

}

int main()

{

       sigset_t set, pendset;

       struct sigaction action1, action2;

       if(sigemptyset(&set) < 0)

              perror("sigemptyset");

       if(sigaddset(&set, SIGQUIT) < 0)

              perror("sigaddset");

       if(sigaddset(&set, SIGINT) < 0)

              perror("sigaddset");

       if(sigprocmask(SIG_BLOCK, &set, NULL) < 0)

              perror("sigprocmask");

       else

       {

              printf("block/n");

              sleep(5);

       }

       if(sigprocmask(SIG_UNBLOCK, &set, NULL) < 0)

              perror("sigprocmask");

       else

              printf("unblock/n");

       while(1)

       {

              if(sigismember(&set, SIGINT))

              {

                     sigemptyset(&action1.sa_mask);

                     action1.sa_handler = my_func;

                     sigaction(SIGINT, &action1, NULL);

              }

              else if(sigismember(&set, SIGQUIT))

              {

                     sigemptyset(&action2.sa_mask);

                     action2.sa_handler = SIG_DFL;

                     sigaction(SIGTERM, &action2, NULL);

              }

       }

}

3. 共享内存(大型数据传输)

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

#include <string.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#define BUFSZ 2048

int main()

{

       int shmid;

       char *shmadd;

       key_t key;

       if((key = ftok(".", 'a')) == -1)

       {

              perror("ftok");

              exit(1);

       }

       if((shmid = shmget(IPC_PRIVATE, BUFSZ, 0666)) < 0)

       {

              perror("shmget");

              exit(1);

       }

       else

       {

              printf("created shared-memory: %d/n", shmid);

              system("ipcs –m");

       }

       if((shmadd = shmat(shmid, 0, 0)) < (char*)0)

       {

              perror("shmat");

              exit(1);

       }

       else

       {

              printf("attached shared-memory/n");

              system("ipcs –m");

       }

       if(shmdt(shmadd) < 0)

       {

              perror("shmdt");

              exit(1);

       }

       else

       {

              printf("dettached shared-memory/n");

              system("ipcs -m");

       }

       exit(0);

}

4. 消息队列(少量数据传输)

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

#include <string.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#define BUFSZ 512

struct message

{

       long msg_type;

       char msg_text[BUFSZ];

};

int main()

{

       int qid;

       key_t key;     

       int len;

       struct message msg;

       if((key = ftok(".", 'a')) == -1)

       {

              perror("ftok");

              exit(1);

       }

       if((qid = msgget(key, IPC_CREAT | 0666)) == -1)

       {

              perror("msgget");

              exit(1);

       }

       printf("opened queue %d/n", qid);

       puts("Please enter the message to queue:");

       if((fgets(msg.msg_text, BUFSZ, stdin)) == NULL)

       {

              puts("no message");

              exit(1);

       }

       msg.msg_type = getpid();

       len = strlen(msg.msg_text);

       if(msgsnd(qid, &msg, len, 0) < 0)

       {

              perror("message posted");

              exit(1);

       }

       printf("message is :%s/n", msg.msg_text);

       if(msgctl(qid, IPC_RMID, NULL) < 0)

       {

              perror("msgctl");

              exit(1);

       }

       exit(0);

}

5. 守护进程

守护进程(daemon)是生存期长的一种进程。它们常常在系统引导装入时启动,在系统关闭时终止。因为它们没有控制终端,所以说它们是在后台进程的。所有守护进程都以超级用户优先级运行。所有守护进程的父进程都init进程。守护进程一般是进程组的首进程。

查看守护进程命令:

ps –ef

创建守护进程的步骤:

(1)       创建子进程, 父进程退出。

保证子进程不是一个进程组的首进程,是调用setsid调用的必要的前提条件。

(2)       调用setsid以创建一个新的会话,并担任该会话组的组长。调用setsid作用有三:

(a)       成为新的会话组(一个或多个进程组)的首进程。

(b)       成为一个新进程组的首进程。

(c)       脱离控制终端。

(3)       改变当前目录为根目录

chdir(“/”);

(4)       重设文件权限掩码

unmask(0);表示打开所有文件权限

(5)       关闭不再需要的文件描述符

#include <stdio.h>

#include <stdlib.h>

#include<string.h>

#include <fcntl.h>

#include <sys/types.h>

#include <unistd.h>

#include <sys/wait.h>

#define MAXFILE 65535

int main()

{

       pid_t pc;

       int i, fd, len;

       char *buf = "This is a Dameon/n";

       len = strlen(buf);

       pc = fork();

       if(pc < 0)

       {

              printf("error fork/n");

              exit(1);

       }

       else if(pc > 0)

       {

              exit(0);

       }

       setsid();

       chdir("/");

       umask(0);

       for(i = 0; i < MAXFILE; i++)

       close(i);

       while(1)

       {

              if((fd = open("/tmp/dameon.log", O_CREAT | O_WRONLY | O_APPEND, 0600)) < 0)

              {

                     perror("open");

                     exit(1);

              }

              write(fd, buf, len+1);

              close(fd);

              sleep(5);

       }

}

继续阅读