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:

 

posted @ 2016-09-08 18:17  IT由零开始  阅读(495)  评论(0编辑  收藏  举报