TLPI-Chapter 29线程:介绍

一个进程可以包含多个线程,多个线程共享同一份全局内存区域,包括初始化数据段(initialized data)、未初始化数据段(uninitialized data)以及堆内存段(heap segment).

对于某些应用而言,线程要优于进程:

1.进程间信息难以共享,必须使用进程间通信IPC方式,在进程间进行消息通信。

2.使用fork创建进程带价较高。

线程解决了上面两个问题:

1.线程之间能够方便、快速共享信息,需要使用线程同步技术(互斥锁 条件变量)

2.创建线程比创建进程快(实现线程是通过clone()系统调用)

TLPI-Chapter 32 线程:线程取消

在通常情况下,程序中的多个线程并发执行,每个线程各司其职,直至其决意退出,随即会调用函数pthread_exit()或者从线程启动函数中返回。

有时候,需要将一个线程取消,亦即向线程发送一个请求,要求其立即退出。比如一组线程正在执行一个运算,一旦某个线程检测到错误发生,需要其他线程退出,取消线程的功能这时就能派上用场。

另一种情况,一个图形用户界面(GUI)驱动的应用程序可能会提供一个“取消”按钮,以便用户可以终止后台某一线程正在执行的任务。这种情况下,主线程(控制图形用户界面)需要请求后台线程退出。

本文记录学习TLPI一书第32章线程:线程取消内容,讨论POSIX线程的取消机制。

......

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()所拥有的功能,但是在某些应用中任然......

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......