TLPI-Chapter 48 System V 共享内存

共享内存允许两个或多个进程共享物理内存的同一块区域(通常称为段)。由于一个共享内存段会称为一个进程用户空间内存的一部分,因此这种IPC机制无需内核介入。所有需要做的就是让一个进程将数据复制进共享内存中,并且这部分数据会对其他所有共享同一个段的进程可用。

与管道或消息队列要求发送进程将数据从用户空间的缓冲区复制进内核内存和接收进程将数据从内核内存复制进用户空间的缓冲区的做法相比,这种IPC技术的速度更快。

共享内存允许两个或多个进程共享内存的同一个分页。通过共享内存交换数据无需内核干涉。一旦一个进程将数据复制进一个共享内存段中之后,数据将会立刻对其它进程可以见。共享内存是一种快速的IP......

TLPI-Chapter 45 System V IPC介绍

这节开始学习System V IPC,书中后面会介绍POSIX IPC,两者之间的区别可以参考stackoverflow上的一篇回答。system-v-ipc-vs-posix-ipc

System V IPC包含消息队列、信号量和共享内存。

消息队列

消息队列用来在进程之间传递消息。消息队列与管道有点像,但存在两个重大差异:

第一消息队列是存在边界的,这样读者和写者之间以消息进行通信,而不是通过无分隔符的字节流进行通信。

第二每条消息包括一个整型的type字段,并且可以通过类型选择消息而无需以消息被写入的顺序来读取消息。

信号量

信号量允许多个进程同步它们的动作。一个信号量......

TLPI-Chapter 44 管道和FIFO

管道由pipe函数创建,提供一个单向数据流。pipe函数返回两个文件描述符:fd[0]与fd[1],前者打开来读,后者打开来写。

管道的典型用途是在父子进程之前提供进程间通信手段。首先,由父进程创建一个管道,然后调用fork创建子进程。如果父进程关闭管道的读出端,子进程关闭管道的写入端。在父子进程间就形成了一个单向数据流。

通常我们在shell中输入一个像下面的命令时:

cmd1 | cmd2 | cmd3

将会创建三个进程和其中的两个管道。将每个进程的读出端复制到相应进程的标准输入,把每个管道的写入端复制到相应进程的标准输出。

#include <unistd.h>......

TLPI-Chapter 42 共享库高级特性

动态加载库

核心dlopen API由以下函数(所有这些函数都在SUSv3进行了规定)构成。

dlopen()函数打开一个共享库,返回一个供后续调用使用的句柄。

dlsym()函数在库中搜索一个符号并返回其地址。

dlclose()函数关闭之前由dlopen()打开的库。

dlerror()函数返回一个错误消息字符串,在调用上述函数中的某个函数发生错误时可以使用这个函数来获取错误消息。

dlopen函数

dlopen函数将名libfilename的共享库加载进调用进程的虚拟地址空间并增加该库的打开引用计数。

#include <dlfcn.h>

void *d......

TLPI-Chapter 41 共享库基础

题外话:在编译程序时包含调试信息

使用gcc/cc编译时指定-g选项可以使得程序中包含调试信息,所带来的影响是可执行文件的体积增大。

如果使用strip(1)命令: strip - Discard symbols from object files,可以从可执行文件和库文件中删除调试信息。

#include <stdio.h>

int sum(int a,int b)

{

return a + b;

}

int g_count = 0;

int main()

{

printf("Hello world.\n");

return 0;

}

[......

TLPI-Chapter 55 文件加锁

应用程序的一个常见需求是从一个文件中读取一些数据,然后将这些数据写回文件。只要在一个时刻只有一个进程以这种方式使用文件就不会存在问题,但当多个进程同时更新一个文件时问题就出现了。本文将介绍两组不同的给文件加锁的API。

flock()函数对整个文件加锁

fcntl()对一个文件的部分区域加锁

使用flock()给文件加锁

函数原型:

#include <sys/file.h>

int flock(int fd,int operation);

fcntl()函数提供了比该函数更为强大的功能,并且所拥有的功能也覆盖了flock()所拥有的功能,但是在某些应用中任然......

pthread_join和pthread_detach

关于pthread_join

函数原形:

#include <pthread.h>

int pthread_join(pthread_t thread,void **retval);

return 0 on success,or a positive error number on error

调用pthread_join的线程会阻塞,如果线程已经终止,pthread_join会立即返回。

如果线程简单的返回,那么rval_ptr被设置成线程的返回值;如果调用了pthread_exit,则可将一个无类型指针返回,在pthread_join中对其进行访问;如果线程被......

The Linux Programming Interface

本文复习The Linux Programming Interface一书中,一些知识点的总结,源代码存在github中,在源代码中添加部分注释,用于学习与总结。

确定glibc版本

使用如下命令:

[root@centos7-10 files]# ldd /usr/bin/ls | grep libc

libcap.so.2 => /lib64/libcap.so.2 (0x00007f7d5a0c1000)

libc.so.6 => /lib64/libc.so.6 (0x00007f7d59aeb000)

然后在shell窗口中执行如下命令可以看到:

......

TLPI-Chapter 30 线程:线程同步

互斥量/*************************************************************************\

* Copyright (C) Michael Kerrisk, 2017. *

* *

* This program is free software. You may use, modify, and redistribut......

TLPI-Chapter 26 监控子进程

/*************************************************************************\

* Copyright (C) Michael Kerrisk, 2017. *

* *

* This program is free software. You may use, modify, and redistribute i......