2. Linux线程控制

2.1 创建线程

   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;失败返回错误码 

来看以下demo体会pthread_create的使用:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
void *thr_start(void *arg)
   while(1)
     pthread_t tid = pthread_self();
     printf("---odniary-----%s-%lu\n",(char*)arg,tid);
     sleep(1);
  return NULL;
int main()
  int ret;
  pthread_t tid;
  pthread_t mtid = pthread_self();    //pthread_self()   --- 可以获取线程自身ID
  ret = pthread_create(&tid,NULL,thr_start,(void*)"hello");
  if(ret != 0)
    printf("thread create error\n");
    return -1;
  while(1)
    printf("--------main-----------mtid:%lu----ctid:%lu\n",mtid,tid);
    sleep(1);
  return 0;

再来回顾上述demo:pthread_create函数会产生一个线程ID,存放在第一个参数指向的地址中,pthread_ create函数第一个参数指向一个虚拟内存单元,该内存单元的地址即为新创建线程的线程ID, 属于NPTL线程库的范畴。线程库的后续操作,就是根据该线程ID来操作线程的。 在上面的demo里我们就是用了NPTL线程库提供的pthread_self(),获取线程ID。

2.2 终止线程

如果想终止某个线程而不是整个进程,可以有以下三个方法:

  1. 从线程函数return。但这种方法对主线程不适用,从main函数return相当于调用exit。
  2. 线程可以调用pthread_ exit终止自己。
  3. 一个线程可以调用pthread_ cancel终止同一进程中的另一个线程。

2.2.1 pthread_eixt函数

    void pthread_exit(void *value_ptr); 
    参数    value_ptr:value_ptr不要指向一个局部变量。
    返回值:无返回值,跟进程一样,线程结束的时候无法返回到它的调用者(自身

2.2.2 pthread_cancel函数

 int pthread_cancel(pthread_t thread); 
 参数    thread:线程ID 
 返回值:成功返回0;失败返回错误码

2.3 线程等待

为什么需要线程等待?

  • 已经退出的线程,其空间没有被释放,仍然在进程的地址空间内。
  • 创建新的线程不会复用刚才退出线程的地址空间。
    下面的函数就承担了这一作用,调用后,会等待线程结束
 int pthread_join(pthread_t thread, void **value_ptr); 
 参数:thread  --- 线程ID   
      value_ptr --- 它指向一个指针,后者指向线程的返回值 返回值:成功返回0;失败返回错误码

调用该函数的线程将挂起等待,直到id为thread的线程终止。thread线程以不同的方法终止,通过pthread_join得到 的终止状态是不同的。

2.4 线程分离

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

int pthread_detach(pthread_t thread);

来看以下demo,体会detach的使用。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
void *thread_run(void *arg){
    pthread_detach(pthread_self());
    printf("%s\n",(char*)arg);
    return NULL;
int main()
    pthread_t tid;
    if(pthread_create(&tid,NULL,thread_run,"thread_run ...") != 0){
        printf("create thread error\n");
        return 1;
    int ret = 0;
    sleep(1);
    if(pthread_join(tid,NULL) == 0){
        printf("pthread wait success\n");
        ret = 0;
    }else{
        printf("pthread wait failed\n");
        ret = 1;
    return ret;
                                    线程相关函数1. 线程相关函数1.1 pthread_exit函数1.2 pthread_join函数1.3 pthread_cancel函数1.4 pthread_detach
1. 线程相关函数
线程终止
从线程函数return。这种方法对主线程不适用,从main函数return相当于调用exit。
线程可以调用pthread_ exit终止自己。
一个线程可以调用pthread_ cancel终止同一进程中的另一个线程。
1.1 pthread_exit函数
exit()是终止进程,并不是终止
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void 
                                    什么是线程?为什么要有多线程?
       一家公司需要生产某种产品,然后为生产这种产品提供了各种原材料和几层楼的资源。而这件产品是有很多个零件组成的,各个零件需要的材料可能是不同的,即,有些零件之间的制造是不相互影响的。现在要生产一种产品,由A、B两种零件组成。公司分配了1、2、3这三层楼(2楼是用于生产的该产品的各种器械)用于生产该产品。假设加工零件A是将材料都准备好了放到2楼的机器里边,...
                                    什么是线程先来举一个我们生活中的实例,我们都使用过一个强大的软件—迅雷。那你必然知道迅雷有一个边下边播的功能,我们在下载的时候还能同时进行观看。这就是一个多线程实例。 
线程是进程内部的执行分支。
打开迅雷软件—–向系统内核索要资源,启动“迅雷”进程,。
开始下载一个电影—–从索要的资源中调度分配一部分资源,启动下载线程。
开始播放电影—–再索要的资源中调度分配一部分资源次从,启动播放线程。
#include &amp;amp;amp;lt;pthread.h&amp;amp;amp;gt;
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
(2...
                                    线程的概念:线程是运行在进程内的一个基本执行流,和进程共享地址空间及资源(类似于父子进程共享地址空间),但每个也有自己的私有资源。进程强调独占性 每个进程都有它独立的地址空间,包括Text Segment、Data Segment等线程强调共享性 线程的共享资源:  1.进程代码段        2.进程的公有数据(利用这些共享的数据,线程很容易的...