Linux线程浅析[线程初始化和销毁,线程分离]

Linux线程浅析[线程初始化和销毁,线程分离]

  1. 线程的初始化和销毁
  2. 什么是线程的分离
  3. 线程分离函数

线程的初始化和销毁

回想一下线程的创建pthread_create的时候,第二个参数是pthread_attr_t,那么这个参数类型代表的是什么??attr是特征特性的缩写,所以这个参数的意思大概是创建线程的特征特性.
所以先了解一下这个参数的结构体类型:

 typedef struct{
    int etachstate; //线程的分离状态
    int schedpolicy; //线程的调度策略
    struct sched schedparam;//线程的调度参数
    int inheritsched; //线程的继承性
    int scope; //线程的作用域
    size_t guardsize; //线程栈末尾的警戒缓冲区大小
    int stackaddr_set; //线程栈的设置
    void* stackaddr; //线程栈的启始位置
    size_t stacksize; //线程栈大小
}pthread_attr_t;
在上面我们可以看到,关于这个结构体中的相关参数

 但是我们在创建一个线程的参数的时候,该怎么去创建也是一个问题.因为初始化的时候之前的例子中传入的都是NULL参数,后面会提到两个函数,是关于初始化和销毁线程参数类型的.
 
pthread_attr_init和pthread_attr_destory函数

#include<ptrhead.h>
int pthread_attr_init(pthread_attr_t *attr)
int pthead_attr_destory(pthread_attr_t *attr)
成功返回0,否则返回错误编号
pthread_attr_init函数是初始化线程参数的
pthread_attr_destory函数是销毁线程的参数的

如代码:
    pthread_attr_t attr;
    int err;
    if((err=pthread_attr_init(&attr))!=0){
        perror("create attr error");        
    }
    if((error =pthread_attr_destory(&attr))!=0){
        perror("destory attr error");
    }
    然后去修改结构体中的参数,在pthread_create()函数进行线程创建的时候将其传入进去;

什么是线程的分离

对比进程,子进程在销毁的时候使用wait和waitpid函数,都是去等待子进程资源的回收,同时也有singal去捕捉SIG_CHLD信号来进行调用wait函数去回收子进程,那么在线程中会不会也有这样的一个函数呢?或者类似的策略,让线程执行完毕之后,能够自动的监听检测.然后去释放其资源???答案是:我目前还没有遇到这一快相关的知识积累.但是在线程中却提供了这样一个分离策略,就是在线程执行完毕之后,能够自动回收线程所占有的资源
定义:

 线程分离策略就是当线程执行完毕之后,能够由系统自动去回收线程所占有的资源的这样的一个策略.

线程分离函数

#include<pthread.h>
int pthread_attr_getdetachstat(const pthread_attr_t *restrict attr,int *detachstate);
int pthread_attr_setdetachstat(const pthread_attr_t *attr,int detachstate);
返回:成功返回0,出错返回错误编号
detachstat取值:
PTHREAD_CREATE_JOINABLE(默认值)正常启动线程
PTHREAD_CREATE_DETACHED以分离状态启动线程

 注意:

  • 以默认方式启动的线程,在线程结束后不会自动释放占有的系统资源,要在主控线程中调用pthread_join()后才会释放
  • 以分离状态启动的线程,在线程结束后会自动释放所占有的系统资源,这个时候就不需要调用pthread_join方法了
  • 分离属性在网络通讯中使用的比较多;
  • 以分离状态创建的线程就不需要去调用pthread_join了,同时以分离状态去创建的线程,是不能够获取线程返回的结果
/*
 * ===========================================================================
 *
 *       Filename:  pthread_detach.c
 *    Description:  
 *        Version:  1.0
 *        Created:  2017年03月27日 22时02分37秒
 *       Revision:  none
 *       Compiler:  gcc
 *         Author:   (), 
 *        Company:  
 *
 * ===========================================================================
 */

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

void * th_function(void* argv){
  int *agv = (int *) argv;
  printf("agv:%d\n",agv);
  int i=0;
  for(i =0; i<agv; i++){
     printf("thread:%lx,i:%d\n",pthread_self(),i);
     sleep(1);
  }
  return (void*)0;
}

void outDeched(pthread_attr_t* attr){
  int result_code;
  int detach;
  if((result_code = pthread_attr_getdetachstate(attr,&detach))!=0){
      perror("get error");
  }else{
    if(detach == PTHREAD_CREATE_JOINABLE){
      printf("PTHREAD_CREATE_JOINABLE\n");
    }else if(detach ==PTHREAD_CREATE_DETACHED ){
      printf("PTHREAD_CREATE_DETACHED\n");
    }else{
      printf("other detach");
  }
  }
}


int main(int argc,char * argv[]){
  pthread_attr_t attr;
  pthread_t turtle ,rabbit;

  int err;
  int entach;
  if((err = pthread_attr_init(&attr)) != 0){
      perror("create attr error");
  }

  int result_code;
  //获得响应的分离策略,一般的是默认策略,即不分离状态,需要使用pthread_join去阻塞回收
  if((result_code = pthread_attr_getdetachstate(&attr,&entach))!=0){
      perror("get error");
  }else{
  } 
  outDeched(&attr);

  int create_result;
  if((create_result = pthread_create(&turtle,&attr,th_function,(void*)50))!=0){
      perror("creat turtle error");
  }
  printf("==========================");
  //给rabbit去设置detached的属性
  if((result_code = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED))!=0){
      perror("set error");
  }
  outDeched(&attr);

  if((create_result = pthread_create(&rabbit,&attr,th_function,(void*)40))!=0){
      perror("create rabbit error");  
  }

  //销毁这样的一个pthread_attr_t结构体
  if((err = pthread_attr_destroy(&attr))!=0){
      perror("destory pthread error");
  }

  //因为turtle是默认的join方式进行创建的,所以其需要调用pthread_join去释放
  pthread_join(turtle,NULL);
  printf("main thread:%lx ended\n",pthread_self());
  return 0;
}

 如上所陈述:turtle采用的是默认的JOIN方式去启动,而rabbit采用的是DETACHED的方式去启动,注意:
 detached的方式去启动的时候,是不需要通过pthread_join方法去阻塞等待回收的,并且detached的方式启动的,这个时候线程是不会有返回值返回来的

 谢谢访问,写的不好或者不对的地方,请及时指出,代码是可以直接进行run的,有兴趣的可以copy下去玩一下,线程部分相对比较难理解,但是确实是非常重要
 有兴趣的可以看一下线程的属性,这两篇博客相对来说比较全:
 
 http://blog.csdn.net/scanery/article/details/7242768
 http://www.360doc.com/content/15/0725/16/25419505_487332488.shtml
 

欢迎持续访问博客

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 创建一个基于对话框的应用程序。并增加如图所示控件;分别为3个进度条控件关联三个进度条类型的变量;并在对话框的初始化函数中,设定进度条的范围;为编辑框关联一个整型的变量;为12个按钮添加消息处理函数; 2. 定义结构体:用做线程函数的参数传递 typedef struct Threadinfo{ CProgressCtrl *progress;//进度条对象 int speed; //进度条速度 int pos; //进度条位置 } thread,*lpthread; 3. 为对话框增加三个句柄,用于标识各个线程; HANDLE hThread1; //线程1线程句柄 HANDLE hThread2; //线程2线程句柄 HANDLE hThread3; //线程3线程句柄 在增加三个结构体类型的变量,用做线程函数的参数传递; HANDLE hThread1; //线程1线程句柄 HANDLE hThread2; //线程2线程句柄 HANDLE hThread3; //线程3线程句柄 4. 新增一个静态的全局变量,用于记录所有线程的状态:static int GlobalVar=10000; 5. 声明并编写线程函数,注意只能有一个参数,且函数的返回值类型也是固定的;函数名可以自定义; DWORD WINAPI ThreadFun(LPVOID pthread);//线程入口函数 6. 在启动按钮的消息处理函数中编写如下代码: thread1.progress=&m_progress1;//进度条对象 thread1.speed=100;//速度 thread1.pos=0;//初始位置 hThread1=CreateThread(NULL,0,ThreadFun,&thread1;,0,0);//创建并开始线程 if (!hThread1) { MessageBox("创建线程失败"); } 7. 编写线程函数(一般是一个死循环,或者需要花费时间很长的算法!否者就失去了多线程的意义) DWORD WINAPI ThreadFun(LPVOID pthread) //线程入口函数 { lpthread temp=(lpthread)pthread;//参数强制转换为结构体类型 temp->progress->SetPos(temp->pos); //设置被传递过来的进度条的位置 while(temp->posspeed); /设置速度 temp->pos++; //增加进度 temp->progress->SetPos(temp->pos); //设置进度条的新位置 GlobalVar--; if(temp->pos==20) { temp->pos=0; //进度条满则归0 } } return true; } 8. 在挂起按钮函数中,编写如下代码: if(SuspendThread(hThread1)==0xFFFFFFFF) { MessageBox("挂起失败!进程可能已经死亡或未创建!"); return; } 9. 在执行按钮函数中,编写如下代码: if(ResumeThread(hThread1)==0xFFFFFFFF) { MessageBox("执行失败!进程可能已经死亡或未创建!"); return; } 10. 在停止按钮函数中,编写如下代码: if(TerminateThread(hThread1,0))//前些终止线程 { CloseHandle(hThread1);//销毁线程句柄 } else { MessageBox("终止进程失败!"); } 11. 为应用程序添加WM_TIMER消息,实时更新全局变量的值到编辑框;

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值