Linux 线程浅析

什么是线程

  • 在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是一个进程内部的控制序列。
  • 一切进程至少都有一个执行线程。

进程和线程

  • 进程是承担分配资源的基本单位,线程是调度的基本单位。
  • Linux下线程是轻量级进程。也就是说,Linux下是用进程模拟线程的。每一个用户态线程,在内核中都对应一个调度实体,也拥有自己的进程描述符。 

POSIX线程库

  • 与线程有关的函数构成了一个完整的系列,绝大多数函数的名字都是以“pthread_t”打头的。
  • 要使用这些库函数,要引入头文件#include <pthread.h>t
  • 链接这些库函数时,要使用编译器命令的”-lpthread”选项
功能:创建一个新的线程 
函数:int pthread_create(pthread_t* thread, const pthread_attr_t* attr,void* (start_routine) (void ), void *arg); 
参数: 
thread:返回线程id 
attr:设置线程的属性,attr为NULL表示使用默认属性 
start_routine:是个函数地址,线程启动后要执行的函数。 
arg:传给线程启动函数的参数。 
返回值:成功返回0,失败返回错误码。

创建线程

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

void* rout()
{
    while(1)
    {   
        printf("I am thread 1!\n");
        sleep(1);
    }   
}


int main()
{
    pthread_t tid;
    int ret = pthread_create(&tid,NULL,rout,NULL);
    if(ret != 0)
    {   
        perror("create!");
        exit(EXIT_FAILURE);
    }   

    while(1)
    {   
        printf("I am main thread!\n");
        sleep(1);
    }   
    return 0;
}

线程ID

现在介绍线程ID,不同于pthread_t类型的线程ID,和进程ID一样,线程ID是pid_t类型的变量,而且是用来唯一标示线程的一个整型变量。查看线程ID方法如下:


pthread_create函数会产生一个线程id,存放在第一个参数指向的地址中,该线程id是指用户级线程id。 
线程库提供了相关接口,可以用来获得线程自身的id。 
pthread_t类型:实质上是一个进程空间上的一个地址。
线程库NPTL提供了一个pthread_self函数,可以获得线程自身的ID
pthread_t pthread_self(void); 

线程终止

如果需要只终止某个线程而不终⽌整个进程,可以有三种⽅法:
1. 从线程函数return。这种⽅法对主线程不适⽤,从main函数return相当于调⽤exit。
2. 线程可以调⽤pthread_ exit终⽌⾃⼰。

3. ⼀个线程可以调⽤pthread_ cancel终⽌同⼀进程中的另⼀个线程。

pthread_exit函数

功能:线程终⽌
原型
void pthread_exit(void *value_ptr);
参数
value_ptr:value_ptr不要指向⼀个局部变量。
返回值:⽆返回值,跟进程⼀样,线程结束的时候⽆法返回到它的调⽤者(⾃⾝)

需要注意,pthread_exit或者return返回的指针所指向的内存单元必须是全局的或者是⽤malloc分配的,不能在线
程函数的栈上分配,因为当其它线程得到这个返回指针时线程函数已经退出了。

pthread_cancel函数

功能:取消⼀个执⾏中的线程
原型
int pthread_cancel(pthread_t thread);
参数
thread:线程ID
返回值:成功返回0;失败返回错误码

线程等待

为什么需要线程等待?
已经退出的线程,其空间没有被释放,仍然在进程的地址空间内。

创建新的线程不会复⽤刚才退出线程的地址空间。

功能:等待线程结束
原型
int pthread_join(pthread_t thread, void **value_ptr);
参数
thread:线程ID
value_ptr:它指向⼀个指针,后者指向线程的返回值
返回值:成功返回0;失败返回错误码

线程分离

默认情况下,新创建的线程是joinable的,线程退出后,需要对其进⾏pthread_join操作,否则⽆法
释放资源,从而造成系统泄漏。
如果不关心线程的返回值,
join是⼀种负担,这个时候,我们可以告诉系统,当线程退出时,⾃动
释放线程资源
 。

int pthread_detach(pthread_t thread);
可以是线程组内其他线程对目标线程进⾏分离,也可以是线程⾃⼰分离 :
pthread_detach(pthread_self());
joinable和分离是冲突的,⼀个 线程不能既是joinable⼜是分离的 。

void *thread(void* arg)
{
    pthread_detach(pthread_self()); //分离自身
    printf("%s\n",(char*)arg);
    return NULL;
}

int main()
{
    int ret = 0;
    pthread_t tid;
    pthread_create(&tid,NULL,thread,"thread 1 is running!");
    sleep(1);
    if(pthread_join(tid,NULL) == 0)
    {   
        printf("pthread wait success!\n");
        ret = 0;
    }   
    else
    {   
        printf("pthread wait faild!\n");
        ret = 1;
    }   
    return ret;
}

运行结果:说明线程分离后不能被等待


猜你喜欢

转载自blog.csdn.net/ihaha233/article/details/80299123