Linux线程:概念、特点、线程间资源共享情况

1. 线程概念

线程是轻量级的进程;Linux中,线程本质上仍是进程。

进程是OS分配资源的最小单位,线程是OS调度的最小单位。

NPTL

当前Linux线程库为redHat开发的NPTL,查看本地线程库版本:

getconf GNU_LIBPTHREAD_VERSION


 2. 线程特点

(1)轻量级的进程(Light-Weight Process),也有PCB;

(2)无论是创建进程的fork,还是创建线程的pthread_create,底层都是调用内核函数clone;

(3)若复制(深拷贝,但有“COW”优化)父进程地址空间,则为进程;若共享(浅拷贝)父进程地址空间,则为线程。

(4)Linux内核不区分进程和线程,只在上层应用区分;

(5)线程操作函数pthread_*是库函数,而非系统调用。

线程优点

(1)提高并发性;

(2)开销小;

(3)共享数据方便;

线程缺点

(1)库函数,不稳定;

(2)调试困难;

(3)信号支持不好。


3. 线程间共享资源和非共享资源

(1)线程共享资源

        ① 文件描述符表

        ② 各信号处理方式

        ③ 当前工作目录

        ④ 用户ID和组ID

        ⑤ 内存地址空间中的 .txt、.data、.bss、.heap、.共享库

(2)线程非共享资源

        ① 线程id

        ② 处理器现场和栈指针(内核栈)

        ③ 线程栈(用户空间栈)

        ④ errno变量

        ⑤ 信号屏蔽字

        ⑥ 调度优先级

线程共享资源测试:

主线程、子线程对全局num、堆区变量修改:

#include
#include
#include
#include

int num = 100;  // 全局变量

void* func(void* arg) {

    int* pn = (int*)arg;

    printf("修改前, 子线程中的全局变量num = %d, 堆区变量*p = %d\n", num, *pn);
    num++;
    (*pn)++;
    printf("修改后, 子线程中的全局变量num = %d, 堆区变量*p = %d\n", num, *pn);

    return NULL;
}

int main(int argc, const char* argv[]) {

    pthread_t tid;
    int ret = -1;
    int* p = NULL;

    memset(&tid, 0, sizeof(tid));

    // 分配堆空间
    p = malloc(sizeof(int));
    if (NULL == p) {
        perror("malloc");
        return 1;
    }
    memset(p, 0, sizeof(int));

    *p = 10;

    // 创建一个线程
    ret = pthread_create(&tid, NULL, func, (void*)p);
    if (0 != ret) {
        printf("线程创建失败...\n");
        return 1;
    }

    printf("按回车键继续.\n");
    getchar();
    printf("修改后, 主线程中的全局变量num = %d, 堆区变量*p = %d\n", num, *p);

    free(p); // 只能释放一次,因为堆区是共享的,只有一个*p

    return 0;
}

运行结果:

Linux线程:概念、特点、线程间资源共享情况_第1张图片

 可知同一进程中的线程共享.data区、heap区,此外还共享代码区、.bss区。

你可能感兴趣的:(Linux多线程编程,Linux多线程,多线程,linux)