c++多线程三

pthread

POSIX Threads简称Pthreads,Pthreads是线程的POSIX标准,该标准定义了一套C程序语言的类型、函数和常量。定义在pthread.h头文件和一个线程库里,大约有100个API,所有API都带有"pthread_"前缀,可以分为4大类:

  • 线程管理(Thread
    management):包括线程创建(creating)、分离(detaching)、连接(joining)及设置和查询线程属性的函数等。

  • 互斥锁(Mutex):"mutual
    exclusion"的缩写,用了限制线程对共享数据的访问,保护共享数据的完整性。包括创建、销毁、锁定和解锁互斥锁及一些用于设置或修改互斥量属性等函数。

  • 条件变量(Condition
    variable):用于共享一个互斥量的线程间的通信。包括条件变量的创建、销毁、等待和发送信号(signal)等函数。

  • 读写锁(read/write lock)和屏障(barrier):包括读写锁和屏障的创建、销毁、等待及相关属性设置等函数。

  • POSIX信号量(semaphore)和Pthreads一起使用,但不是Pthreads标准定义的一部分,被定义在POSIX.1b,
    Real-time extensions (IEEE Std1003.1b-1993)标准里。因此信号量相关函数的前缀是"sem"而不是"pthread"。

  • 消息队列(Message queue)和信号量一样,和Pthreads一起使用,也不是Pthreads标准定义的一部分,被定义在IEEE Std1003.1-2001标准里。消息队列相关函数的前缀是"mq_"。

             pthread_           线程本身和各种相关函数
 
        pthread_attr_           线程属性对象
 
       Pthread_mutex_           互斥锁
 
   pthread_mutexattr_           互斥锁属性对象
 
        pthread_cond_           条件变量
 
    pthread_condattr_           条件变量属性对象
 
      pthread_rwlock_           读写锁
 
  pthread_rwlockattr_           读写锁属性对象
 
        pthread_spin_           自旋锁
 
     pthread_barrier_           屏障
 
 pthread_barrierattr_           屏障属性对象
 
                sem_           信号量
 
                 mq_           消息队列

绝大部分Pthreads的函数执行成功则返回0值,不成功则返回一个包含在<errno.h>头文件中的错误代码。很多操作系统都支持Pthreads,比如Linux、MacOS X、 Android 和Solaris,因此使用Pthreads的函数编写的应用程序有很好的可移植性,可以在很多支持Pthreads的平台上直接编译运行。

创建线程

typedef rt_thread_t pthread_t;

pthread_t是rt_thread_t类型的重定义,定义在pthread.h头文件里。rt_thread_t是RT-Thread的线程句柄(或线程标识符),是指向线程控制块的指针。在创建线程前需要先定义一个pthread_t类型的变量。每个线程都对应了自己的线程控制块,线程控制块是操作系统用于控制线程的一个数据结构,它存放了线程的一些信息,例如优先级,线程名称和线程堆栈地址等。线程控制块及线程具体信息在RT-Thread编程手册的线程调度与管理一章有详细的介绍。

int pthread_create (pthread_t *tid,
                   const pthread_attr_t *attr,
                   void *(*start) (void *), void *arg);
参数作用
tid指向线程句柄(线程标识符)的指针,不能为NULL
attr指向线程属性的指针,如果使用NULL,则使用默认的线程属性
start线程入口函数地址
arg传递给线程入口函数的参数

线程脱离deatch

 int pthread_detach (pthread_t thread);

调用此函数,如果pthread线程没有结束,则将thread线程属性的分离状态设置为detached;当thread线程已经结束时,系统将回收pthread线程占用的资源。

线程脱离示例代码
以下程序会初始化2个线程,它们拥有相同的优先级,并按照时间片轮转调度。2个线程都会被设置为脱离状态,2个线程循环打印3次信息后自动退出,退出后系统将会自动回收其资源。

#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
 
/* 线程控制块 */
static pthread_t tid1;
static pthread_t tid2;
 
/* 函数返回值检查 */
static void check_result(char* str,int result)
{
    if (0 == result)
    {
        printf("%s successfully!\n",str);
    }
    else
    {
        printf("%s failed! error code is %d\n",str,result);
    }
}
 
/* 线程1入口函数*/
static void* thread1_entry(void* parameter)
{
    int i;
 
    printf("i'm thread1 and i will detach myself!\n");
    pthread_detach(pthread_self());        /*线程1脱离自己*/
 
    for (i = 0;i < 3;i++)    /* 循环打印3次信息 */
    {
        printf("thread1 run count: %d\n",i);
        sleep(2);    /* 休眠2秒 */    
    }
 
    printf("thread1 exited!\n");
    return NULL;
}
 
/* 线程2入口函数*/
static void* thread2_entry(void* parameter)
{
    int i;
 
    for (i = 0;i < 3;i++)    /* 循环打印3次信息 */
    {
        printf("thread2 run count: %d\n",i);
        sleep(2);    /* 休眠2秒 */    
    }
 
    printf("thread2 exited!\n");
    return NULL;
}
/* 用户应用入口 */
int rt_application_init()
{
    int result;
 
    /* 创建线程1,属性为默认值,分离状态为默认值joinable,
     * 入口函数是thread1_entry,入口函数参数为NULL */
    result = pthread_create(&tid1,NULL,thread1_entry,NULL);
    check_result("thread1 created",result);
 
    /* 创建线程2,属性为默认值,分离状态为默认值joinable,
     * 入口函数是thread2_entry,入口函数参数为NULL */
    result = pthread_create(&tid2,NULL,thread2_entry,NULL);
    check_result("thread2 created",result);
 
    pthread_detach(tid2);    /* 脱离线程2 */
 	//while(1);
    return 0;
}

线程join

int pthread_join (pthread_t thread, void **value_ptr);

以下程序代码会初始化2个线程,它们拥有相同的优先级,相同优先级的线程是按照时间片轮转调度。2个线程属性的分离状态为默认值joinable,线程1先开始运行,循环打印3次信息后结束。线程2调用pthread_join()阻塞等待线程1结束,并回收线程1占用的资源,然后线程2每隔2秒钟会打印一次信息。

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



/* 线程控制块*/
static pthread_t tid1;
static pthread_t tid2;

/* 函数返回值检查 */
static void check_result(char* str,int result)
{
    if (0 == result)
    {
        printf("%s successfully!\n",str);
    }
    else
    {
        printf("%s failed! error code is %d\n",str,result);
    }
}

/* 线程1入口函数 */
static void* thread1_entry(void* parameter)
{
    int i;

    for (int i = 0;i < 3;i++)    /* 循环打印3次信息 */
    {
        printf("thread1 run count: %d\n",i);
        sleep(2);    /* 休眠2秒 */
    }

    printf("thread1 exited!\n");
    return NULL;
}

/* 线程2入口函数*/
static void* thread2_entry(void* parameter)
{
    int count = 0;
    void* thread1_return_value;

    /* 阻塞等待线程1运行结束 */
    pthread_join(tid1, NULL);

    /* 线程2打印信息开始输出 */
    while(1)
    {
        /* 打印线程计数值输出 */
        printf("thread2 run count: %d\n",count ++);
        sleep(2);    /* 休眠2秒 */
    }

    return NULL;
}

/* 用户应用入口 */
int rt_application_init()
{
    int result;
    /* 创建线程1,属性为默认值,分离状态为默认值joinable,
     * 入口函数是thread1_entry,入口函数参数为NULL */
    result = pthread_create(&tid1,NULL,thread1_entry,NULL);
    check_result("thread1 created",result);

    /* 创建线程2,属性为默认值,分离状态为默认值joinable,
     * 入口函数是thread2_entry,入口函数参数为NULL */
    result = pthread_create(&tid2,NULL,thread2_entry,NULL);
    check_result("thread2 created",result);

    return 0;
}
int main()
{
    rt_application_init();
    while(1);
    return 0;
}

线程退出exit

  void pthread_exit(void *value_ptr);

这个程序会初始化2个线程,它们拥有相同的优先级,相同优先级的线程是按照时间片轮转调度。2个线程属性的分离状态为默认值joinable,线程1先开始运行,打印一次信息后休眠2秒,之后打印退出信息然后结束运行。线程2调用pthread_join()阻塞等待线程1结束,并回收线程1占用的资源,然后线程2每隔2秒钟会打印一次信息。


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

/* 线程控制块 */
static pthread_t tid1;
static pthread_t tid2;

/* 函数返回值核对函数 */
static void check_result(char* str,int result)
{
    if (0 == result)
    {
        printf("%s successfully!\n",str);
    }
    else
    {
        printf("%s failed! error code is %d\n",str,result);
    }
}

/* 线程1入口函数*/
static void* thread1_entry(void* parameter)
{
    int count = 0;
    while(1)
    {
        /* 打印线程计数值输出 */
        printf("thread1 run count: %d\n",count ++);
        sleep(2);    /* 休眠2秒 */
        printf("thread1 will exit!\n");

        pthread_exit(0);    /* 线程1主动退出 */
    }
}

/* 线程2入口函数*/
static void* thread2_entry(void* parameter)
{
    int count = 0;

    /* 阻塞等待线程1运行结束 */
    pthread_join(tid1,NULL);
    /* 线程2开始输出打印信息 */
    while(1)
    {
        /* 打印线程计数值输出 */
        printf("thread2 run count: %d\n",count ++);
        sleep(2);    /* 休眠2秒 */
    }
}

/* 用户应用入口 */
int rt_application_init()
{
    int result;

    /* 创建线程1,属性为默认值,分离状态为默认值joinable,
     * 入口函数是thread1_entry,入口函数参数为NULL */
    result = pthread_create(&tid1,NULL,thread1_entry,NULL);
    check_result("thread1 created",result);

    /* 创建线程2,属性为默认值,分离状态为默认值joinable,
     * 入口函数是thread2_entry,入口函数参数为NULL */
    result = pthread_create(&tid2,NULL,thread2_entry,NULL);
    check_result("thread2 created",result);

    return 0;
}

int main()
{
    rt_application_init();
    while(1);
    return 0;
}

以上所有资料参考自:https://www.bookstack.cn/read/rtthread-manual-doc/16.2.md

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值