线程的基本使用

参考文献

Linux --线程编程

进程

  • 系统中程序执行和资源分配的基本单位
  • 每个进程有自己的数据段、代码段和堆栈段
  • 在进行切换时需要有比较复杂的上下文切换

线程

  • 减少处理机的空转时间,支持多处理器以及减少上下文切换开销, 比创建进程小很多
  • 进程内独立的一条运行路线
  • 处理器调度的最小单元,也称为轻量级进程
  • 可以对进程的内存空间和资源进行访问,并与同一进程中的其他线程共享

线程的基本使用

线程的创建

 int pthread_create(pthread_t * thread, const pthread_attr_t * attr, void *(*func)(void *), void *restrict arg);
  • 第一个参数 传入一个线程结构体 线程标示符号
  • 第二个参数 用来配置线程属性 基本为NULL
  • 第三个参数 为回调函数
  • 第四个参数 是参数

线程的结束

     void
     pthread_exit(void *value_ptr);

返回一个指针 相当于 return (void*)value_ptr
注意
这里不能调用exit() 否则会结束当前进程 而不是结束线程

线程的等待 类似:waitpid()

int
 pthread_join(pthread_t thread, void **value_ptr);
  • thread 需要等待的线程
  • value_ptr 线程的返回参数

代码

#include 
#include 
#include 

void *thrd_func1(void *arg);
void *thrd_func2(void *arg);

int main(){
    pthread_t tid1,tid2;
    void *tret;
    // 创建线程tid1,线程函数thrd_func1
    if (pthread_create(&tid1,NULL,thrd_func1,NULL)!=0) {
        printf("Create thread 1 error!\n");
        exit(1);
    }
    // 创建线程tid2,线程函数thrd_func2
    if (pthread_create(&tid2,NULL,thrd_func2,NULL)!=0) {
        printf("Create thread 2 error!\n");
        exit(1);
    }

    void *tret;
    // 等待线程tid1结束,线程函数返回值放在tret中
    if (pthread_join(tid1,&tret)!=0){
        printf("Join thread 1 error!\n");
        exit(1);
    }
    printf("Thread 1 exit code: %d.\n",(int *)tret);
    // 等待tid2结束,线程函数返回值放在tret中
    if (pthread_join(tid2,&tret)!=0){
        printf("Join thread 2 error!\n");
        exit(1);
    }

    printf("Thread 2 exit code: %d.\n",(int *)tret);

    return 0;
}

void *thrd_func1(void *arg){
    printf("Thread 1 exiting!\n");
//    sleep(3);
    return ((void *)1); // 自动退出线程
}

void *thrd_func2(void *arg){
    printf("Thread 2 exiting!\n");
    pthread_exit((void *)2);  // 线程主动退出,返回(void *)2
}  

线程取消

参考文献

     int
     pthread_cancel(pthread_t thread);
      #include 

     int
     pthread_setcancelstate(int state, int *oldstate);

     int
     pthread_setcanceltype(int type, int *oldtype);

     void
     pthread_testcancel(void);


pthread_setcancelstate() 函数用来设置当前线程的“可取消性”状态,并且将先前的状态返回到oldstate引用中。“可取消性”状态的合法值分别是:PTHREAD_CANCEL_ENABLE 和 PTHREAD_CANCEL_DISABLE.这个函数还可以查询当前线程的“可取消性”状态,即把第一个参数设为NULL。


pthread_setcanceltype() 函数用来设置当前线程的“可取消类型”,并且将先前的类型返回到oldtype引用中。
“可取消类型”的合法值分别是:

  • PTHREAD_CANCEL_DEFERRED :线程接收到取消操作后,直到运行到“可取消点”后取消。
  • PTHREAD_CANCEL_ASYNCHRONOUS :线程接收到取消操作后,立即取消。

“可取消性”和“可取消类型”存在于任意一个新建线程中,包括主线程

默认设置是

  • PTHREAD_CANCEL_ENABLE
  • PTHREAD_CANCEL_DEFERRED。

pthread_testcancel()函数用来在当前线程创建一个“可取消点”。如果当前线程是不能取消的,则这个函数无效

#include 
#include 
#include 

void *thrd_func1(void *arg);
void *thrd_func2(void *arg);

pthread_t tid1,tid2;

int main(){
    // 创建线程tid1,线程函数thrd_func1
    if (pthread_create(&tid1,NULL,thrd_func1,NULL)!=0) {
        printf("Create thread 1 error!\n");
        exit(1);
    }
    // 创建线程tid2,线程函数thrd_func2
    if (pthread_create(&tid2,NULL,thrd_func2,NULL)!=0) {
        printf("Create thread 2 error!\n");
        exit(1);
    }
    // 等待线程tid1退出
    if (pthread_join(tid1,NULL)!=0){
        printf("Join thread 1 error!\n");
        exit(1);
    }else
        printf("Thread 1 Joined!\n");
    // 等待线程tid2退出
    if (pthread_join(tid2,NULL)!=0){
        printf("Join thread 2 error!\n");
        exit(1);
    }else
        printf("Thread 2 Joined!\n");

    return 0;
}

void *thrd_func1(void *arg){
//    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); // 设置其他线程可以cancel掉此线程

    while(1) {
        printf("Thread 1 is running!\n");
        sleep(1);
    }
    pthread_exit((void *)0);
}

void *thrd_func2(void *arg){
    printf("Thread 2 is running!\n");
    sleep(5);
    if (pthread_cancel(tid1)==0)  // 线程tid2向线程tid1发送cancel
        printf("Send Cancel cmd to Thread 1.\n");
        
    pthread_exit((void *)0);
}

你可能感兴趣的:(线程的基本使用)