C 语言多线程(上)

一,线程创建

1.1 每一个线程都有一个唯一的线程ID,ID类型为pthread_t,这个ID是一个无符号长整形数,如果想要得到当前线程的线程ID,可以调用如下函数:


pthread_t pthread_self(void); // 返回当前线程的线程ID


1.2线程创建


**#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void ), void arg);


参数
thread: 传出参数,是无符号长整形数,线程创建成功, 会将线程ID写入到这个指针指向的内存中

attr: 线程的属性, 一般情况下使用默认属性即可, 写NULL

start_routine: 函数指针,创建出的子线程的处理动作,也就是该函数在子线程中执行。

arg: 作为实参传递到 start_routine 指针指向的函数内部
返回值:线程创建成功返回0,创建失败返回对应的错误号

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>

// 子线程的处理代码
void* working(void* arg)
{
    printf("我是子线程, 线程ID: %ld\n", pthread_self());
    for(int i=0; i<9; ++i)
    {
        printf("child == i: = %d\n", i);
    }
    return NULL;
}

int main()
{
    // 1. 创建一个子线程
    pthread_t tid;
    pthread_create(&tid, NULL, working, NULL);
    printf("子线程创建成功, 线程ID: %ld\n", tid);
    
    // 2. 子线程不会执行下边的代码, 主线程执行,
    printf("我是主线程, 线程ID: %ld\n", pthread_self());
    for(int i=0; i<3; ++i)
    {
        printf("i = %d\n", i);
    }
    return 0;
}


程序分析: 在main函数里面创建出子线程之后,子线程就开始和主线程抢夺资源(这取决于操作系统对线程的优先级管理),程序运行就有随机性,可能主线程运行完之前就被抢占了CPU,即i=2之前就被进入子线程处理函数(即子线程抢到了CPU,子线程完成之后,驻主线程重新拿到CPU控制权。也有可能是主线程执行完毕,子线程没有抢到CPU

            随机情况1
在这里插入图片描述
            随机情况2
在这里插入图片描述

二,线程退出

在编写多线程程序的时候,如果想要让线程退出,但是不会导致虚拟地址空间的释放(针对于主线程),我们就可以调用线程库中的线程退出函数,只要调用该函数当前线程就马上退出了,并且不会影响到其他线程的正常运行,不管是在子线程或者主线程中都可以使用。


#include <pthread.h>
void pthread_exit(void *retval);


参数
线程退出的时候携带的数据,当前子线程的主线程会得到该数据。如果不需要使用,指定为NULL

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>

// 子线程的处理代码
void* working(void* arg)
{
    sleep(1);
    printf("我是子线程, 线程ID: %ld\n", pthread_self());
    for(int i=0; i<9; ++i)
    {
        if(i==6)
        {
            pthread_exit(NULL);	// 直接退出子线程
        } 
        printf("child == i: = %d\n", i);
    }
    return NULL;
}

int main()
{
    // 1. 创建一个子线程
    pthread_t tid;
    pthread_create(&tid, NULL, working, NULL);

    printf("子线程创建成功, 线程ID: %ld\n", tid);
    
    // 2. 子线程不会执行下边的代码, 主线程执行
    printf("我是主线程, 线程ID: %ld\n", pthread_self());
    for(int i=0; i<3; ++i)
    {
        printf("i = %d\n", i);
    }

    // 主线程调用退出函数退出, 地址空间不会被释放
    pthread_exit(NULL);
    
    return 0;
}

程序分析: 在main函数里面创建出子线程之后,子线程就开始和主线程抢夺资源(这取决于操作系统对线程的优先级管理),主线程运行完之前就被抢占了CPU,即i=2之前就被进入子线程处理函数(即子线程抢到了CPU,子线程完成之后,主线程重新拿到CPU控制权。也有可能是主线程执行完毕,子线程没有抢到CPU ,但是由于使用线程推出函数不会释放虚拟可见,所以子线程一定可以执行完毕
           
           在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

书中藏着宇宙

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

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

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

打赏作者

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

抵扣说明:

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

余额充值