【Linux系统编程】29.线程、pthread_self、pthread_create

目录

线程

三级映射

线程共享资源

线程非共享资源

线程优缺点

优点

缺点

pthread_self

返回值

pthread_create

参数thread

参数attr

参数3

参数4

返回值

测试代码1

测试结果

测试代码2

测试结果

线程

线程概念:

  • 进程:有独立的进程地址空间,有独立的PCB,是分配资源的最小单位。

  • 线程:有独立的PCB,没有独立的进程地址空间,是最小的执行单位。

  • LWP是CPU执行的最小单位。

ps -Lf 进程ID
ps -Lf 2813

三级映射

线程共享资源

  1. 文件描述符表。

  2. 每种信号的处理方式。

  3. 当前工作目录。

  4. 用户ID和组ID。

  5. 内存地址空间。(.text/.data/.bss/heap/.共享库)

  6. 共享全局变量。

线程非共享资源

  1. 线程ID。

  2. 处理器现场和栈指针(内核栈)。

  3. 独立的栈空间(用户栈空间)。

  4. errno变量。

  5. 信号屏蔽字。

  6. 调度优先级。

线程优缺点

优点

  1. 提高程序并发性。

  2. 开销小。

  3. 数据通信、共享数据方便。

缺点

  1. 库函数不稳定。

  2. 调式、编写困难,gdb不支持。

  3. 对信号支持不友好。

pthread_self

       获取线程ID。其作用对应进程中getpid()函数。线程ID是进程内部,识别标志。两个进程间,线程 ID 允许相同。

       线程ID:pthread_t 类型。

       本质:在Linux下为无符号整数(%lu),其他系统中可能是结构体实现。

man 3 pthread_self

返回值

成功:0

失败:无

pthread_create

创建一个新线程。

man 3 pthread_create

参数thread

传出参数,新创建的子线程ID。

参数attr

线程属性。

NULL:表示使用默认属性。

参数3

子线程回调函数。创建成功后,pthread_create函数返回时,该函数会自动执行。

参数4

子线程回调函数的参数。没有参数时,传NULL。

返回值

成功:0

失败:错误号

测试代码1

创建一个线程,并输出内容。 

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>

void *HuiDiao_HanShu()
{
    printf("这是子线程的回调函数,子线程的进程ID是%d,子线程ID是%lu。\n", getpid(), pthread_self());
}

int main(int argc, char *argv[])
{
    int flag;
    pthread_t ZiXianCheng_ID;                                           //子线程ID
    flag = pthread_create(&ZiXianCheng_ID, NULL, HuiDiao_HanShu, NULL); //创建子线程
    if (flag != 0)
    {
        perror("创建子线程错误");
        exit(1);
    }
    printf("这是主线程,进程ID是%d,线程ID是%lu。\n", getpid(), pthread_self());
    sleep(1);

    return 0;
}

测试结果

测试代码2

创建多个子线程。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>

void *HuiDiao_HanShu(void *arg)
{
    int num;
    num = (int )arg+1;
    sleep(num);
    printf("这是第%d个子线程的回调函数,子线程的进程ID是%d,子线程ID是%lu。\n", num, getpid(), pthread_self());
}

int main(int argc, char *argv[])
{
    int flag, i;
    pthread_t ZiXianCheng_ID; //子线程ID
    for (i = 0; i < 5; i++)
    {
        flag = pthread_create(&ZiXianCheng_ID, NULL, HuiDiao_HanShu, (void *)i); //创建子线程,传参采用值传递
        if (flag != 0)
        {
            perror("创建子线程错误");
            exit(1);
        }
    }

    printf("这是主线程,进程ID是%d,线程ID是%lu。\n", getpid(), pthread_self());
    sleep(i+1);

    return 0;
}

测试结果

  • 13
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
pthread_create函数用于创建一个新的线程,其函数原型为: ```c int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); ``` 其中,参数thread是一个指向pthread_t类型的指针,用于存储新线程的ID;参数attr是一个指向pthread_attr_t类型的指针,用于设置线程的属性,一般为NULL;参数start_routine是一个指向函数的指针,该函数将作为新线程的入口点;参数arg是一个指向void类型的指针,用于传递给start_routine函数的参数。 pthread_self函数用于获取当前线程的ID,其函数原型为: ```c pthread_t pthread_self(void); ``` 下面是一个示例程序,演示了pthread_create函数和pthread_self函数的用法和程序的执行顺序: ```c #include <stdio.h> #include <pthread.h> void *thread_func(void *arg) { pthread_t tid = pthread_self(); printf("New thread created with ID %lu\n", tid); return NULL; } int main() { pthread_t tid; printf("Main thread ID is %lu\n", pthread_self()); pthread_create(&tid, NULL, thread_func, NULL); pthread_join(tid, NULL); return 0; } ``` 程序首先输出了主线程的ID,然后调用pthread_create函数创建了一个新线程,并将其ID存储在tid变量中。pthread_create函数的第三个参数是一个指向函数的指针,该函数将作为新线程的入口点,这里我们传递了thread_func函数的地址。thread_func函数中调用了pthread_self函数获取当前线程的ID,并输出到控制台。最后,主线程调用pthread_join函数等待新线程结束。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

因心,三人水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值