zoukankan      html  css  js  c++  java
  • Unix/Linux编程实践教程(二:socket、多线程、进程间通信)

    同一接口不同的数据源:

    协同进程:

    fdopen以文件描述符为参数:

    fopen和popen:

    为了实现popen,必须在子进程中调用sh,因为只有shell本身即/bin/sh可以运行任意shell命令:

    popen的实现:

     

    访问数据:

    系统调用socket创建一个socket:

     

    htons(16位)、htonl(32位)、ntohs、ntohl这些函数用于网络字节序与主机字节序转换。名字由来:host to network long。

    connect:

     使用SIGCHLD来阻止僵尸问题:

    到前面的章节补一下signal调用:

    waitpid提供了wait函数超集的功能:

    但是不知道上面waitpid第二个参数是指向整型值的指针,只有一个值而不是多个值。???

    HTTP请求和应答:

    http服务器处理请求:

     许可证服务器。

    一个通信系统的例子:

    TCP和UDP的比较:

    数据报socket使用sendto和recvfrom。

    get_internet_address函数:

    服务端通过recvfrom可得客户端的IP信息:

     分布式许可证系统方案:

     Unix域文件名作为socket地址:

     使用多线程的实例:

    互斥锁:

    线程和fork进程一些差别:

     互斥锁和条件变量:

    创建不需返回的独立线程:

    select系统调用:

    其中,readfds的类型为fd_set

    select调用示例中的showdata函数:

    其中fd_set据说是以位图实现的:

    #define __NFDBITS (8 * sizeof(unsigned long))                //每个ulong型可以表示多少个bit,
    #define __FD_SETSIZE 1024                                          //socket最大取值为1024
    #define __FDSET_LONGS (__FD_SETSIZE/__NFDBITS)     //bitmap一共有1024个bit,共需要多少个ulong
    
    typedef struct {
        unsigned long fds_bits [__FDSET_LONGS];                 //用ulong数组来表示bitmap
    } __kernel_fd_set;
     
    typedef __kernel_fd_set   fd_set;
    
    对应的操作:
    //每个ulong为32位,可以表示32个bit。
    //fd  >> 5 即 fd / 32,找到对应的ulong下标i;fd & 31 即fd % 32,找到在ulong[i]内部的位置
     
    #define __FD_SET(fd, fdsetp)   (((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] |= (1<<((fd) & 31)))             //设置对应的bit
    #define __FD_CLR(fd, fdsetp)   (((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] &= ~(1<<((fd) & 31)))            //清除对应的bit
    #define __FD_ISSET(fd, fdsetp)   ((((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] & (1<<((fd) & 31))) != 0)     //判断对应的bit是否为1
    #define __FD_ZERO(fdsetp)   (memset (fdsetp, 0, sizeof (*(fd_set *)(fdsetp))))                             //memset bitmap

    命名管道FIFO:

    IPC方法之三共享内存(前二就是前面的文件管道):

    IPC方法之三共享内存示例:

    其中示例用到的部分函数没有在本书中解释:

    int shmdt(const void *shmaddr)   //(断开共享内存连接)

    int shmctl(int shmid, int cmd, struct shmid_ds *buf)   //(共享内存管理)

    函数传入值
    shmid
    共享内存标识符
    cmd
    IPC_STAT:得到共享内存的状态,把共享内存的shmid_ds结构复制到buf中
    IPC_SET:改变共享内存的状态,把buf所指的shmid_ds结构中的uid、gid、mode复制到共享内存的shmid_ds结构内
    IPC_RMID:删除这片共享内存
    buf
    共享内存管理结构体。具体说明参见共享内存内核结构定义部分

    注:在QT中码了一个使用共享内存的实例,其中myIPC使用共享内存,并加载图片到其中,在sharedMemoryTest中访问该共享内存并显示先前加载的图片,主要相关代码如下:

    myIPC相关代码:
    sharedMemory.setKey("QSharedMemoryExample"
    ); …… sharedMemory.lock(); char *to=(char*) sharedMemory.data(); const char *from=buffer.data().data(); memcpy(to,from,qMin(sharedMemory.size(),size)); sharedMemory.unlock(); sharedMemory.detach();

    sharedMemoryTest相关代码:
    sharedMemory.setKey("QSharedMemoryExample"); 
    sharedMemory.
    lock();
    buffer.setData((
    char*)sharedMemory.constData(),sharedMemory.size());
    buffer.open(QBuffer::ReadOnly);

    in>>image; sharedMemory.unlock();
    sharedMemory.detach();

    QT这里共享内存的setKey函数参数为字符串,这不同于前面说的整型数,不知道会不会最后关联到一个整型数。

    使用文件锁进行编程:

    使用文件锁进行编程示例:

    使用信号量:

    使用信号量示例:

    纵观IPC:

  • 相关阅读:
    输入形如"a-b,b-c,b-d"的字符串,当作相邻路径,计算最远路径
    即时通信软件后端API文档
    Django中,使用redis作为缓存
    Django中,websocket实时通信设置概要
    在Django中,自定义User模型,使用token鉴权,实现注册、登录、修改密码等API
    Django中,用rest_framework写API
    偶尔练习一下,go语言做题目
    关于邮政储蓄卡内钱被盗的思考
    浅谈图片上传之剪切
    JavaScript学习笔记
  • 原文地址:https://www.cnblogs.com/ph829/p/5854045.html
Copyright © 2011-2022 走看看