参考网上的实现,进行了一点改进,本来想用FIFO实现的,后来发现不行,必须使用系统的sendmsg函数,代码格式有点乱,不过功能可以实现,改天有空整理一下~~

讲究看哈~

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include <strings.h>
#include<sys/wait.h>
#include <string.h>
#include <errno.h>
#include <sys/un.h>
#include <sys/uio.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/stat.h>

#define FIFO_NAME "/home/907684/my_fifo_file"
//#define BUFFER_SIZE PIPE_BUF
#define BUFFER_SIZE 10
#define TEN_MEG (1024*10)
#define CONTROLLEN sizeof (struct cmsghdr) + sizeof (int)
#define false 0
#define true 1
//异步写打开FIFO,必须先有读打开FIFO 否则会失败!

int proccess_num=-1;

void show_struct_byte(const char * buf, int len)
{
 if (len <= 0) return;
 
 int i;
 printf("[%d]show struct len :%d. \r\n",proccess_num,len);
 printf("[%d]show struct as string :%s. \r\n *** \r\n",proccess_num,buf);
 
 for(i=0;i<len;i++)
 {
  printf("%d ",(int)(*buf++));
 }
 printf("\r\n[%d]finish show struct byte \r\n", proccess_num);
}

int send_sock_fd(int pipe_fd, int sock_fd)
{
    if (pipe_fd <0 || sock_fd < 0) return false;
     
     
    int bytes = 0,res;
    int return_flag=true;
    printf("[%d]enter send_sock_fd()... \r\n",proccess_num);
    /*    
    char buf_str[] = "firt recieved Client speaking!\n";
    //int ret = write(sock_fd, buf_str, sizeof(buf_str));
    //write() 异常判断...
   
    struct cmsghdr *  cmptr = 0;
    struct msghdr msg;
    struct iovec  iov[1];
    char   buf[2];
   
    iov[0].iov_base = buf;
    iov[0].iov_len  = 2;
    msg.msg_iov = iov;
    msg.msg_iovlen = 1;
    msg.msg_name = NULL;
    msg.msg_namelen = 0;
   
    cmptr = (struct cmsghdr *)malloc(sizeof(struct cmsghdr) + sizeof(int));
    cmptr->cmsg_level = SOL_SOCKET;
    cmptr->cmsg_type  = SCM_RIGHTS;
    cmptr->cmsg_len   = sizeof(struct cmsghdr) + sizeof(int);
    *(int *)CMSG_DATA(cmptr) = sock_fd;
    msg.msg_control = cmptr;
    msg.msg_controllen = sizeof(struct cmsghdr) + sizeof(int);
    
    buf[1] = 0; buf[0] = 1;
    */

char tmpbuf[CONTROLLEN];
     struct cmsghdr *cmptr = (struct cmsghdr *) tmpbuf;
     struct iovec iov[1];
     struct msghdr msg;
     char buf[1];
     iov[0].iov_base = buf;
     iov[0].iov_len = 1;
     msg.msg_iov = iov;
     msg.msg_iovlen = 1;
     msg.msg_name = NULL;
     msg.msg_namelen = 0;
     msg.msg_control = cmptr;
     msg.msg_controllen = CONTROLLEN;
     cmptr->cmsg_level = SOL_SOCKET;
     cmptr->cmsg_type = SCM_RIGHTS;
     cmptr->cmsg_len = CONTROLLEN;
     *(int *)CMSG_DATA (cmptr) = sock_fd;
 
     show_struct_byte((char *)&msg, sizeof(msg));

while (bytes < sizeof(msg))
        {
          printf("[%d]call write()... \r\n",proccess_num);
    
            res = write(pipe_fd, (void *)&msg, sizeof(msg));
            //res = sendmsg(pipe_fd,&msg,0);
           
            printf("[%d]res = %d && errno = %d. \r\n",proccess_num,res,errno);
            if (res == -1 )
            {
              if(errno == EAGAIN)
              {
                 printf("[%d]write no data. try later... \r\n",proccess_num);
                 continue;
               }
               else
               {
               printf("[%d]write error. exit! \r\n",proccess_num);
                fprintf(stderr, "Write error on pipe\r\n");
               
                 return_flag=false; 
                 break;              
               }
            }
            bytes += res;
            printf("[%d]write data:%d bytes, sleep...\r\n",proccess_num,res);
            //sleep(9);
        }
        printf("[%d]Total %d bytes send to fifo. send sock_fd:%d. sizeof(msg):%d \r\n",proccess_num,bytes, sock_fd, sizeof(msg));
        sleep(5);
       
        //free(cmptr);
        //close(sock_fd); //NOT close?
        //close(pipe_fd); //NOT close?
 
    return return_flag;
}

int read_sock_fd(int pipe_fd, int* sock_fd)
{
    if (pipe_fd < 0 || sock_fd < 0) return false;

int bytes = 0, res;
    int return_flag = true;
    printf("[%d]enter read_sock_fd()... \r\n",proccess_num);
    /*
    //get client fd
    char buf[2];
    int newfd = -1;
    struct iovec   iov[1];
    struct msghdr  msg;
    struct cmsghdr * cmptr = (struct cmsghdr *)malloc(sizeof(struct cmsghdr) + sizeof(int));
    
    iov[0].iov_base = buf;
    iov[0].iov_len  = sizeof(buf);
    msg.msg_iov     = iov;
    msg.msg_iovlen  = 1;
    msg.msg_name    = NULL;
    msg.msg_namelen = 0;
    msg.msg_control = cmptr;
    msg.msg_controllen = sizeof(struct cmsghdr) + sizeof(int);
    */
    
     char tmpbuf[CONTROLLEN];
     struct cmsghdr *cmptr = (struct cmsghdr *) tmpbuf;
     struct iovec iov[1];
     struct msghdr msg;
     char buf[1];
     iov[0].iov_base = buf;
     iov[0].iov_len = sizeof (buf);
     msg.msg_iov = iov;
     msg.msg_iovlen = 1;
     msg.msg_name = NULL;
     msg.msg_namelen = 0;
     msg.msg_control = cmptr;
     msg.msg_controllen = CONTROLLEN;
   
        printf("[%d] loop call read() fifo... \r\n", proccess_num);
    while (bytes < sizeof(msg))
        {
          res = read(pipe_fd, &msg, sizeof(msg));
          //res = recvmsg(pipe_fd,&msg,0);
          sleep(2);

printf("[%d]res = %d && errno = %d. \r\n", proccess_num,res,errno);
            if (res == -1 )
            {
              if(errno == EAGAIN)
              {
                 //printf("read no data. try later... \r\n");
                 continue;
               }
               else
               {
               printf("[%d]read error. exit! \r\n",proccess_num);
                fprintf(stderr, "Write error on pipe\r\n");
                 return_flag = false;      
                 break;         
               }
            }
            bytes += res;
            printf("[%d]read data:%d bytes.\r\n",proccess_num,res);
            //sleep(9);
        }
        printf("[%d]%d bytes read from fifo. sizeof(msg):%d \r\n",proccess_num,bytes,sizeof(msg));
       
        //get client socket
        if (return_flag)
        {
         /*
         printf("[%d]read fifo succeed. pase client fd.\r\n",proccess_num);
         printf("[%d]*(int*)CMSG_DATA(cmptr):%d,cmptr:%d.\r\n",proccess_num,*(int*)CMSG_DATA(cmptr),cmptr);
  show_struct_byte((char *)&msg, sizeof(msg)); 
   
         *sock_fd = *(int*)CMSG_DATA(cmptr);
         */
         
         printf("[%d]*(int*)CMSG_DATA(cmptr):%d,cmptr:%d.\r\n",proccess_num,*(int *)CMSG_DATA (cmptr),cmptr);

show_struct_byte((char *)&msg, sizeof(msg)); 
         *sock_fd = *(int *)CMSG_DATA (cmptr);
   
     printf("[%d]CMSG_FIRSTHDR(&msg) ret:%d (should not be 0!) \r\n", proccess_num,CMSG_FIRSTHDR(&msg));

}
        else
        {
         printf("[%d]read fifo failed. set sock_fd = -1. \r\n",proccess_num);
         *sock_fd = -1;
         }
        printf("[%d]get client fd:%d.\r\n",proccess_num,*sock_fd);
        //sleep(5);
        close(pipe_fd);
        //close(sock_fd); //NOT close?
        //free(cmptr);

return return_flag;
}

int init_fifo_write()
{
  //***** fifo *****
    int write_pipe_fd;
    int res;
    int open_mode = O_WRONLY|O_NONBLOCK;

int bytes = 0;
    //char buffer[BUFFER_SIZE + 1] = "hello";

if (access(FIFO_NAME, F_OK) == -1)
    {
        res = mkfifo(FIFO_NAME, 0777);
        if (res != 0)
        {
            fprintf(stderr, "Could not create fifo %s \r\n", FIFO_NAME);
            return -1;
        }
    }

printf("[%d] write opeining FIFO :%s  \r\n", proccess_num, FIFO_NAME);
    //printf("fifo buffer size:%d",BUFFER_SIZE);
   
    int read_fd = open(FIFO_NAME, O_RDONLY | O_NONBLOCK);
    if (read_fd == -1)
    {
      printf("[%d]read open fifo file failed. exit. \r\n",proccess_num);
        return -1;
    }   
   
    write_pipe_fd = open(FIFO_NAME, O_WRONLY|O_NONBLOCK);   
    if (write_pipe_fd == -1)
    {
      printf("[%d]write open fifo file failed. exit. \r\n",proccess_num);
        return -1;
    }  
    printf("[%d]Process %d result %d\r\n",proccess_num, getpid(), write_pipe_fd);
   
    return write_pipe_fd; 
   
   }

int init_fifo_read()
{
    int read_pipe_fd;
    int res;

int open_mode = O_RDONLY|O_NONBLOCK;
    char buffer[BUFFER_SIZE + 1];
    int bytes = 0;

memset(buffer, 0, sizeof(buffer));

printf("[%d] read opeining FIFO :%s  \r\n", proccess_num, FIFO_NAME);
    //printf("fifo buffer size:%d",BUFFER_SIZE);
    read_pipe_fd = open(FIFO_NAME, O_RDONLY|O_NONBLOCK);
    printf("Process %d result %d\r\n", getpid(), read_pipe_fd);

if (read_pipe_fd == -1)
    {
      printf("read open fifo file failed. exit. \r\n");
        return -1;
    }  
    printf("Process %d result %d\r\n", getpid(), read_pipe_fd);
   
    return read_pipe_fd; 
 }
 //***** fifo *****

//************************ send socket fd
static struct sockaddr_un addr = {0}; 
static int s_create_usockfd()
{
 static char* path = "/home/907684/test/fd_send/share_fd";

int sockfd; 
 addr.sun_family = AF_UNIX;    
 strcpy(addr.sun_path, path);
 sockfd = socket(PF_UNIX, SOCK_DGRAM, 0);    
 if(sockfd == -1)
 {
  printf("create unix sockfd failed, %d, %s\n", errno, strerror(errno));        
  return 0;    
 }    
 else
 {
  printf("create unix sockfd ok\n");    
 }

//还需要使用bind函数来创建S_IFSOCK类型文件!!!!!!

//否则可能提示文件不存在!!!
 return sockfd;
}

static int s_send_fd(int sockfd, int fd)
{
 struct msghdr msg = {0};
 char ccmsg[CMSG_SPACE(sizeof(fd))];    
 struct cmsghdr* cmsg;     int rv; 
 msg.msg_name = (struct sockaddr*)&addr;    
 msg.msg_namelen = sizeof(addr); 
 msg.msg_control = ccmsg;
 msg.msg_controllen = sizeof(ccmsg); 
 cmsg = CMSG_FIRSTHDR(&msg);    
 cmsg->cmsg_level = SOL_SOCKET;    
 cmsg->cmsg_type = SCM_RIGHTS;
 cmsg->cmsg_len = CMSG_LEN(sizeof(fd)); 
 *(int*)CMSG_DATA(cmsg) = fd;    
 msg.msg_control = ccmsg;
 msg.msg_controllen = cmsg->cmsg_len;    
 msg.msg_flags = 0; 
 printf("sendmsg file fd[%d] to socket fd[%d]\n",fd, sockfd);

rv = (sendmsg(sockfd, &msg, 0) != -1);    
 printf("sendmsg return %d \r\n",rv);
 if(rv)
 {
  printf("sendmsg ok, file fd is %d\n", fd);        
  close(fd);    
 }    
 else
 {
  printf("sendmsg failed to socket fd[%d], errno[%d], error str:%s\n", sockfd, errno, strerror(errno));    
 } 
 printf("send fd[%d] to shared file finish.\r\n", fd);

return rv;
}

int get_fd_to_send()
{
 char * file_shared_path = "/home/907684/test/fd_send/file_shared.txt";
 int sfd = open(file_shared_path, O_CREAT|O_RDWR|O_TRUNC, 0644); 
 return sfd; 
}

//************************ send socket fd

//************************ recv socket fd
static int r_create_usockfd(char* path)
{
    struct sockaddr_un addr = {0};
    int opt = 1;
    int fd;
 
    addr.sun_family = AF_UNIX;
 
    unlink(path);
    strcpy(addr.sun_path, path); 
 
    fd = socket(PF_UNIX, SOCK_DGRAM, 0);
 
    if(bind(fd, (struct sockaddr*)&addr, sizeof(addr))){
        printf("[%d]recv bind failed, %d, %s\n",proccess_num, errno, strerror(errno));
    }
    else{
        printf("[%d]recv bind ok\n", proccess_num);
    }
 
    return fd;
}
 
static int r_recv_fd(int fd)
{
    struct msghdr msg = {0};
    int rv = 0;
    int cfd = -1;
    char ccmsg[CMSG_SPACE(sizeof(cfd))];
    struct cmsghdr* cmsg;
 
    msg.msg_control = ccmsg;
    msg.msg_controllen = sizeof(ccmsg);
 
    while(1){
        rv = recvmsg(fd, &msg, 0);
        if(rv == -1){
            printf("recvmsg failed, return %d, %d, %s\n", rv, errno, strerror(errno));
            sleep(1);
        }
        else{
            printf("[%d]recvmsg ok.\n",proccess_num);
            break;
        }
    }
 
    cmsg = CMSG_FIRSTHDR(&msg);

int client_fd=*(int*)CMSG_DATA(cmsg);
    printf("[%d]recieved client socket fd[%d].\n",proccess_num,client_fd);

return client_fd;
}

int get_share_fd()
{
    int sfd = socket(AF_INET, SOCK_STREAM, 0);
    sfd = socket(AF_INET, SOCK_STREAM, 0);  // waste some fd
 
    static char* path = "/home/907684/test/fd_send/share_fd";
    int sockfd = r_create_usockfd(path);
    int cfd = r_recv_fd(sockfd);
    return cfd;
}

void send_msg_to_client(int cfd)
{
    char* str = "This is the second proccess speaking.\n";
    printf("[%d]write string to recieved file fd[%d]. string[%s]\r\n",proccess_num, cfd,str);
    int res = write(cfd, str, strlen(str));
    if(res<0)
    {
        printf("write error. res:%d\r\n",res);
    }

}

//************************ recv socket fd

int main(int argc, char ** argv)
{
 pid_t pid;
 char *msg;
 int n,i,j;
 int exit_code;
 int res=0,WR_fifo_fd,RD_fifo_fd;
 
 //***** socket *****
 int listenfd,connfd;
 socklen_t clilen;
 struct sockaddr_in cliaddr,servaddr;
 
 listenfd = socket(AF_INET,SOCK_STREAM,0);
 
 //set non_block
 int flags = fcntl(listenfd, F_GETFL, 0);
 if( -1 == fcntl(listenfd, F_SETFL, flags|O_NONBLOCK) )
 {
  printf("Set NONBLOCK for socket fd %d failed", listenfd);
  exit(1);
 }

bzero(&servaddr,sizeof(servaddr));
 servaddr.sin_family = AF_INET;
 servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
 servaddr.sin_port = htons(8060);
 
 bind(listenfd, (struct sockaddr*)&servaddr, sizeof(struct sockaddr));
 listen(listenfd, 1024);
 //***** socket *****
 
 printf("start.\r\n");
 
 for( i=0;i<3;i++)
 {
  pid=fork();
  proccess_num=i;
  if(pid == 0 || pid == -1)
  {
   printf(" not fork.\r\n");
   break;
  }
 }
 
 if (pid == -1)
 {
  printf("fork error.\r\n");
  exit(1);
 }
 else if(pid == 0)
 {
  //child procces.
  //********
  printf("[%d] enter for...\r\n",proccess_num);
  
  if (proccess_num == 1) // 1 write fifo
  {
   printf("[%d] init_fifo_write.\r\n",proccess_num);

res = init_fifo_write();
   if (res == -1)
   {
    printf("init fifo write failed. exit.");
    exit(EXIT_FAILURE);
    }
   WR_fifo_fd = res;
  }
  
  if (proccess_num == 2) // 2 read fifo
  {
   printf("[%d] init_fifo_read. \r\n",proccess_num);
   res = init_fifo_read();
   if (res == -1)
   {
    printf("init fifo read failed. exit.");
    exit(EXIT_FAILURE);
    }
   RD_fifo_fd = res;
  }
  
  printf("[%d] child loop call accept() .\r\n",proccess_num);
  for(;;)
  {
    //printf("[%d] sleep 2 sec.\r\n",proccess_num);
    sleep(1);

//read fifo .
    if (proccess_num == 2) // 2 read fifo
    {
     int clifd=-1;
     //printf("[%d] fifo read.\r\n",proccess_num);

int shared_fd;

shared_fd = get_share_fd();
     send_msg_to_client(shared_fd);

/*     
     res = read_sock_fd(RD_fifo_fd,&clifd);
     if (res != true)
     {
      printf("[%d]read socket fd failed! \r\n",proccess_num);
     }
     else
     {
      printf("[%d]read socket fd succeed! fd:%d \r\n",proccess_num,clifd);
      //send some data to client
      printf("send some data to client! \r\n");
      char buf_str[] = "This is second recieved Client!\n";
      int ret = write(clifd, buf_str, sizeof(buf_str));  
      printf("write ret:%d. buf_str size:%d \r\n", ret,sizeof(buf_str));    
     
      printf("[%d] close client fd:%d \r\n",proccess_num,clifd);
      time_t t;
      time(&t);
      printf("[%d]time: %ld\n",proccess_num,t);
      close(clifd);
     }*/
    }
    else if (proccess_num == 1) // 1 write fifo
    {
     clilen = sizeof(cliaddr);
     //printf("[%d] child call accept() .\r\n",proccess_num);
     if((connfd = accept(listenfd,(struct sockaddr*)&cliaddr, &clilen)) < 0)
     {
      //printf("[%d] accept failed. fd: %d.\r\n",proccess_num,connfd);
      if(errno == EAGAIN)
      {
       //printf("[%d] accept EAGAIN.continue...\r\n",proccess_num);
       continue;
      }
      else
      {
       printf("[%d] accept error.\r\n",proccess_num);
       exit(1);
      }
     }
     else
     {
      printf("[%d] accept succeed. fd:%d \r\n",proccess_num,connfd);
      //sleep(10);
      
      /*if (1) // 1 write fifo
      {
       printf("[%d] fifo write.\r\n",proccess_num);
       //send socket fd to other proccess.
       res = send_sock_fd(WR_fifo_fd, connfd);
       if (res != true)
        printf("[%d]send socket fd %d failed! sleep 10...\r\n",proccess_num,connfd);
       else
        printf("[%d]send socket fd %d succeed! sleep 10...\r\n",proccess_num,connfd);
       sleep(10);
      }*/

//send socket fd to other proccess!
      int local_sockfd = s_create_usockfd();    
      //int client_fd = get_fd_to_send();  
      int client_fd = connfd;
      s_send_fd(local_sockfd,client_fd); 
      
      
      printf("[%d]send socket fd[%d] to other proccess finish. close socket fd. \r\n",proccess_num,connfd);
      close(connfd); //NOT close? 
      time_t t;
      time(&t);
      printf("[%d]time: %ld\n",proccess_num,t); 
     }
    }
  //********
  //exit(0);
  }
 }
 else
 {
  //parent.
  printf("parent wait...\r\n");
  while(1);
  printf("parent exit.\r\n");
  exit(0);
  }
 
 }

client的代码:

#include <stdio.h>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>

#define BUF_LEN    50
/************关于本文档********************************************
*filename: client.c
*purpose: 这是在Linux下用C语言写的一个简单sokcet客户端,用来向共享socket发送消息,以测试共享socket
进程接收消息情况。
使用方法:./client server-ip

更多开源软件,请访问http://fossd.net/?fromuid=32

*********************************************************************/

#include<time.h>

int main(int argc,char* argv[])
{
  if (!argv[1])
  {
   printf(" useage: ./client   [server ip] \r\n eixt. \r\n");
 return -1;
   }
 
   int ret;
   int fd;
  
    int i,len;
   struct sockaddr_in servaddr;
   char buf[BUF_LEN];
   fd_set writefds;

strcpy(buf,"hi, i am client\n");
   fd =  socket(AF_INET,SOCK_STREAM,0);
   if(fd <= 0)
   {
      perror("socket");
   return fd;
   }

servaddr.sin_family = AF_INET;
   servaddr.sin_port = htons(8060);
   servaddr.sin_addr.s_addr = inet_addr(argv[1]);

printf("connect to server... \r\n");
   ret = connect(fd,(struct sockaddr*)&servaddr,sizeof(servaddr));
   if(ret != 0)
   {
      perror("connect");
   return ret;
   }

bzero(buf,BUF_LEN);
   sprintf(buf,"%d hi,i came from client",i);
   len = strlen(buf);
   ret = write(fd,buf,BUF_LEN);
   printf("write ret:%d \r\n",ret);
   if (ret <= 0)
   {
    printf("write ret <= 0 \r\n");
   }

char read_buf[1024]={0};
   if(read(fd, read_buf, 1024) > 0)
   {
    printf("read data:%s \r\n", read_buf  );
   }
   else
   {
    printf("read ret <= 0 \r\n");
    }
  
   printf("read finish. exit.\r\n");
  
   time_t t;
   time(&t);
   printf("time: %ld\n",t);

/*
   while(1)
   {
       int i,len,ret;
 
       for(i = 0; i < 2000; i++)
       {
        bzero(buf,BUF_LEN);
     sprintf(buf,"%d hi,i came from client",i);
     len = strlen(buf);
    
     ret = write(fd,buf,BUF_LEN);

}
       sleep(3);
   }
  */

}

转载于:https://www.cnblogs.com/kai-jiang/p/3235096.html

linux进程之间传递句柄相关推荐

  1. 用WM_COPYDATA消息来实现两个进程之间传递数据

    文着重讲述了如果用WM_COPYDATA消息来实现两个进程之间传递数据. 进程之间通讯的几种方法: 在Windows程序中,各个进程之间常常需要交换数据,进行数据通讯.常用的方法有   1.使用内存映 ...

  2. linux:进程之间的通信

    ipc :进程间通信(InterProcess Communication) 1.管道 同一时间是单向的:父读子写,或父写子读  管道中的数据 ,读走就没了  参数是一个整型数的数组,数组的大小是两个 ...

  3. linux进程互斥要点,linux进程之间互斥

    总所周知,在linux中pthread_mutex_t可以用于同一进程内多个线程之间的同步.我们所需要做的工作,仅仅是定义一个全局的pthread_mutex_t类型变量即可.但是对于进程之间的互斥, ...

  4. linux进程数和句柄数

    注:linux版本CentOS7 目录 一.进程和句柄概念 二.Linux资源限制 1. 用户资源限制 2.service 资源限制 3. 系统资源限制 三. 进程数限制 1. 用户进程数限制 2. ...

  5. Linux 进程间传递文件描述符

    文章目录 文件描述符 文件数据结构 共享文件 UNIX域socket实现传递文件描述符 进程间传递打开的文件描述符,并不是传递文件描述符的值.先说一下文件描述符. 文件描述符 对内核来说,所有打开的文 ...

  6. 不相干进程之间传递文件描述符

    #include <sys/socket.h> #include <fcntl.h> #include <stdio.h> #include <unistd. ...

  7. Linux进程之间通信 消息队列

    使用命令 ipcs -q  查看对应的消息队列 代码 文件接收者 #include <sys/types.h> #include <stdio.h> #include < ...

  8. Linux进程之间通信 信号

    2) SIGINT 程序终止(interrupt)信号, 在用户键入INTR字符(通常是Ctrl-C)时发出,用于通知前台进程组终止进程. 3) SIGQUIT 和SIGINT类似, 但由QUIT字符 ...

  9. Linux中进程间传递文件描述符的方法

    在进行fork调用后,由于子进程会拷贝父进程的资源,所以父进程中打开的文件描述符在子进程中仍然保持着打开,我们很容易的就将父进程的描述符传递给了子进程.但是除了这种情况下,如果想将某个父进程在子进程创 ...

最新文章

  1. GitHub 上有哪些好用的爬虫?
  2. 高中数学?_JAVA
  3. NeurIPS 2018 | 腾讯AI Lab详解3大热点:模型压缩、机器学习及最优化算法
  4. selenium java 参数化_Java+selenium 自动化测试【03】-- 数据驱动之参数化
  5. 工作306:.sync解决子组件改变自身值 父组件也改变自身数值
  6. Mac OS X 显示和隐藏文件
  7. Tpcc-mysql 结果解读
  8. 手机QQ空间如何显示和修改手机机型型号
  9. hdu-2206 IP的计算
  10. Vid2Vid多图详解
  11. 从PROXMOX群集中安全删除节点
  12. Python超详细学员管理系统【面向对象实现】
  13. python中re.sub函数使用
  14. 迷途Emlog模板全站好看的透明变色模板+源码
  15. ffmpeg音视频转单声道16位16K赫兹小端点pcm音频
  16. 重度办公用户,哪款平板更合适?
  17. 上层应用程序是如何访问到底层驱动程序的呢?
  18. 【总结】最好的CV学习小组,超200个课时+10个方向+30个项目,从理论到实践全部系统掌握...
  19. 树莓派人体感应警报(python)HC-SR501红外人体感应
  20. WMS 原型详解 | 产品经理最讨厌的系统

热门文章

  1. 【WebRTC---入门篇】(八)WebRTC核心之RTP Medio 媒体控制与数据统计
  2. 今晚课题:2019-3-22
  3. python2048游戏代码_【Python】用Python实现2048小游戏(源代码,1.0版本)
  4. mongodb一致性协议_mongo的怎么保持事物的一致性-问答-阿里云开发者社区-阿里云...
  5. 光端机使用过程中碰到的九大问题
  6. 什么是程控交换机?程控交换机有哪些优势?
  7. 【渝粤教育】国家开放大学2018年秋季 8177-21T (1)工程经济与管理 参考试题
  8. java期末考试试卷及答案文库_JAVA期末考试试题及答案.docx
  9. mysql5.6 1g内存_1G内存用MySQL5.6还是用MySQL5.5比较好
  10. 工业机器人 答案 韩建海_中国将连续8年成为工业机器人第一大市场,还将持续多久?...