Linux 之 线程创建,退出与回收

Linux 之 线程创建,退出与回收

正文

Linux下的线程

Linux下的线程是轻量级的进程(LWP)。同样的,线程是cpu最小的执行单位,可以多个线程共享同一进程的地址空间。但是每个线程都拥有自己独立的PCB。线程是栈和寄存器的集合。系统以LWP号作为分配资源的依据,可以使用 ps -Lf 进程ID 来查看该进程下的线程。
同一进程内线程间共享资源
文件描述符表,信号处理方式,当前工作目录,用户ID,组ID,内存地址空间(栈除外)。
非共享资源
线程ID,信号屏蔽字,用户栈空间,errno变量,进程调度优先级,线程内核栈(保存线程处理器的现场)和栈指针。

线程的创建

可以使用pthread_create函数来创建线程。
函数原型:
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
参数
thread: 线程ID
attr: 线程属性
start_routine: 入口函数
arg:初始参数
返回值
成功返回 0 ,失败返回错误码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<pthread.h>
#include<errno.h>
void str_error()
{
    
    
  const char * str = strerror(errno);
  write(STDERR_FILENO,str,sizeof(str));
  exit(-1);
}

void *fun(void *arg)
{
    
    
    printf("thread created successful\n");
    return NULL;
}

int main()
{
    
    
     pthread_t tid;
     if(pthread_create(&tid,NULL,fun,NULL) != 0)
     {
    
    
       str_error();
     }
     sleep(1);

}

输出:thread created successful

线程的退出

return退出

在主控线程中return意味着进程的结束,所有线程都会被结束;在其他线程中return只会结束该线程。

exit

exit 意味着结束整个进程,在任何线程中调用exit都会将整个进程退出。

pthread_exit

函数原型:
#include<pthread.h>
void pthread_exit(void *retval);
在线程中调用pthread_exit会将调用的线程退出,并且有又参数retval返回退出值,这个值由pthread_join函数接收。

pthread_cancel

函数原型:
#include <pthread.h>
int pthread_cancel(pthread_t thread);
可以由任意线程调用,取消指定ID的线程。这个取消并不是实时的,需要在系统调用结束的时候才可以被处理。若是一个线s程不产生系统调用,使用该函数无法取消线程,可以使用pthread_testcancel函数来产生系统调用(pthread_testcancel可以产生一次系统调用),被取消的线程pthread_join接收到退出码为PTHREAD_CANCELED。

线程的回收

和进程相似,线程结束后也需要回收(否则会产生僵尸线程),但是不同的是进程只能由其父进程回收,线程额可以由任意线程回收。

pthread_join

函数原型:
#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
参数
thread: 线程ID
retval:用于接收线程退出状态
返回值
成功返回 0 ,失败返回错误码
pthread_join函数效果等同于进程中的waitpid函数,调用后阻塞,等待指定ID的线程结束后返回。
调用前提:回收的线程属性必须是joinable,否则调用失败

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<pthread.h>
#include<errno.h>
void str_error()
{
    
    
  const char * str = strerror(errno);
  write(STDERR_FILENO,str,sizeof(str));
  exit(-1);
}

void *fun(void *arg)
{
    
    
   printf("thread[%ld] created successful\n",pthread_self());
   int *retval = (int *)malloc(4);
   *retval = 1;
   pthread_exit((void*)retval);
}

int main()
{
    
    

     pthread_t tid;
     if(pthread_create(&tid,NULL,fun,NULL) != 0)
     {
    
    
       str_error();
     }
     int *retval = NULL;
     pthread_join(tid,(void*)&retval);
     printf("thread[%ld] exited successful,exit status = %d\n",tid,*retval);
}

输出:
thread[140301426747136] created successful
thread[140301426747136] exited successful,exit status = 1

pthread_detach

函数原型:
#include<pthread.h>
int pthread_detach(pthread_t thread);
参数
thread:指定要分离的线程ID
返回值
成功返回 0 ,失败返回错误码

调用前提:分离的线程属性必须是joinable,否则调用失败

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<pthread.h>
#include<errno.h>
void str_error()
{
    
    
  const char * str = strerror(errno);
  write(STDERR_FILENO,str,sizeof(str));
  exit(-1);
}

void *fun(void *arg)
{
    
    
    sleep(2);
    printf("thread[%ld] created successful\n",pthread_self());
}

int main()
{
    
    

     pthread_t tid;
     if(pthread_create(&tid,NULL,fun,NULL) != 0)
     {
    
    
       str_error();
     }
     pthread_detach(tid);
     printf("main thread exit\n");
     pthread_exit(NULL);

}

输出:
main thread exit
thread[140412667537152] created successful

猜你喜欢

转载自blog.csdn.net/weixin_45074185/article/details/108543215