美文网首页
线程的基本使用

线程的基本使用

作者: 吃苹果的猫C | 来源:发表于2016-08-04 11:40 被阅读31次

参考文献

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 <stdio.h>
#include <stdlib.h>
#include <pthread.h>

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 <pthread.h>

     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 <stdio.h>
#include <stdlib.h>
#include <pthread.h>

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);
}

相关文章

  • 多线程(Pthread/NSThread)

    Pthread简单使用 NSThread基本使用 线程的状态 线程的安全 线程间通讯

  • 012-线程,生产消费模式,线程的通讯

    多线程基础 进程和线程 多线程的基本实现 使用Thread类 基本实现: 实现售票业务: 使用Runnable接口...

  • 1203-AsyncTask详解一:线程池的基本设置

    AsyncTask的内部使用线程池处理并发,要了解它是怎样使用线程池的,那要先了解线程池的基本设置 线程池的基本参...

  • 线程的基本使用

    线程的创建 java创建线程有两种方法​​ 创建Thread的子类 实现Runnable接口 Thread和Run...

  • 线程的基本使用

    线程的引入 在线程未提出之前,操作系统中都是以进程作为能拥有资源和独立运行的基本单位的。但是为了提高系统内程序并发...

  • 线程的基本使用

    参考文献 Linux --线程编程 进程 系统中程序执行和资源分配的基本单位 每个进程有自己的数据段、代码段和堆栈...

  • 线程的基本使用

    1.synchronized之错误的加锁和原因分析 锁一定要加在一个不变的对象上 volatile 关键字,最轻量...

  • Java线程池如何保证线程池的核心线程存活不被销毁?execut

    线程池介绍 基本元素 线程池是一个创建使用线程并能保存使用过的线程以达到服用的对象,他使用workQueue当作阻...

  • Android多线程基础

    线程的基本用法 Android多线程编程并不比Java多线程编程特殊,基本都是使用相同的语法。那么如何创建一个线程...

  • 夜深了,快睡吧-ConcurrentHashMap

    基本使用 运行结果 总结 父类 线程安全hashMap不是线程安全的,如果多线程使用则需手动自己实现锁 concu...

网友评论

      本文标题:线程的基本使用

      本文链接:https://www.haomeiwen.com/subject/nlpcsttx.html