Linux系统编程----线程使用方法

简述

前面描述了Linux下进程的创建过程,在Linux下,我们可以用fork()来开创一个进程空间和父进程搭配执行,但在实际开发中,仍旧多用线程的方法去实现。关于线程与进程间的不同,我们可以通过上面这个该篇博文了解进程和线程关系及区别

相关接口

线程创建

#include<pthread.h>
int pthread_create(pthread_t *restrict tidp,const pthread_attr_t *restrict attr, void *(*start_rin)(void*),void **restrct arg);

//返回值:若成功,返回0,否则,返回值错误编号
  • tidp:线程指向的一片内存单元
  • attr :参数用于定制不同的线程属性,一般使用设置为NULL为默认属性
  • start_in:函数地址
  • arg:参数(如果传递的参数变量不止一个,那么可以使用一个结构体来包含这些变量)
#include<pthread.h>
#include<iostream>
#include<sys/types.h>
#include<unistd.h>
void *test_pthread(void *arg){
  pid_t pid;
  pid = getpid();
  std::cout<<"second test_pthread"<<std::endl;
  return NULL;
}
int main(){
  pthread_t tpid;
  int err=0;
  std::cout<<"first thread "<<std::endl;
  err = pthread_create(&tpid,NULL,&test_pthread,NULL);
  if(err<0){
    perror("thread create erro:");
    exit(1);
  }
  pthread_join(tpid,NULL);
  return 0;
}
wlm@wlm:~/code/example/Linux$ ./thread
first thread 
second test_pthread

关于线程使用上,要注意一些问题,

  • 开辟多个线程,用户是无法掌握线程的执行顺序,线程的执行是交给内核去处理调度的。
  • 新创建的线程可以访问进程的地址空间,并且继承调用线程的浮点环境和信号屏蔽字,该信号挂起信号集会被清除。

线程终止

调用该接口,退出当前线程

  1. pthread_exit

pthread_exit

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

调用该接口,退出当前线程

  • rval_ptr:如果线程是结合态,调用pthread_exit后,会将rval_ptr返回到主线程中
  1. pthread_join
#Include<pthread.h>
int pthread_join(pthread_t thread,void **rval_ptr);
  • pthread_join调用后,会阻塞等待到对应的子线程退出。一文读懂线程的分离状态
  • phtread_join使用涉及到一个线程状态的问题,主线程在创建子线程后,子线程的分离属性默认是结合态的,那么子线程执行结束后的资源释放问题是要交给主线程去释放的,主线程调用pthread_join后,则会阻塞等待子线程执行结束,释放其资源。在Linux中也提供了一个接口pthread_detech,将线程属性设置为分离状态,设置为分离态后,当线程退出后,系统就会将资源进行一个释放。
  1. pthread_cancel(pthread_t tid);
#Include<pthread.h>
int pthread_cancel(pthread_t tid);
//成功返回0,否则返回错误编号

通过调用该接口,来指定要“退出”的线程,这个接口会想指定线程发送退出信号,但是这是一个提醒,接收到该信号的线程可以选择拒绝(涉及线程间的信号控制)。

#include<pthread.h>
#include<iostream>
#include<sys/types.h>
#include<unistd.h>

void *test_pthread(void *arg){
  pid_t pid;
  pid = getpid();
  std::cout<<"second test_pthread"<<std::endl;
  int num=0;
  while(true){
    if(num == 12){
      std::cout<<"pthread_cancel"<<std::endl;
      //pthread_testcancel();
    }
    sleep(1);
    std::cout<<"second:"<<num++<<std::endl;
  }
  std::cout<<"second 退出"<<std::endl;
  return NULL;
}
int main(){
  pthread_t tpid;
  int err=0;
  std::cout<<"first thread "<<std::endl;
  err = pthread_create(&tpid,NULL,&test_pthread,NULL);
  if(err<0){
    perror("thread create erro:");
    exit(1);
  }
  int i=0;
  while(i<5){
    std::cout<<"first"<<i++<<std::endl;
  }
  std::cout<<"取消线程"<<std::endl;
  sleep(5);
  pthread_cancel(tpid);
  std::cout<<"join"<<std::endl;
  pthread_join(tpid,NULL);
  std::cout<<"成功退出"<<std::endl;
  return 0;
}
first thread 
first0
first1
first2
first3
first4
取消线程
second test_pthread
second:0
second:1
second:2
second:3
join
成功退出

这里测试的结果,发送取消信号后,子线程退出。pthread_cancel会提醒指定线程-“你可以退出了”,但退出的时机,则需要在下一次的系统调用(退出态),但是有时候,调用pthread_cancel并不会立即将线程取消,如果有遇到,可以看linux下pthread_cancel无法取消线程的原因

学习了Linux中线程的基本使用,可以发现进程与线程之间可以执行的任务其实多相似,只是二者在操作系统中所处地位不同,我们可以对进程和线程使用的接口进行一个比较

进程接口线程接口描述
forkpthread_create创建新的控制流
exitpthread_exit从现有控制流中退出
waitpidpthread_join从控制流中得到退出状态
getpidpthread_self获取控制流ID
abortpthread_cancel请求控制流的非正常退出

Linux系统编程—进程相关接口介绍

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值