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: