SylixOS单个线程的退出方式

1、开发环境

硬件平台:PC机

软件平台:Windows7,RealEvo-IDE

 

2、知识简介

2.1  概述

       在创建线程实际上就是确定调用该线程函数的入口点,通常使用的函数是pthread_create()。在线程创建之后,就开始运行相关的线程函数,在该函数运行结束,线程也会随着退出。这是其中退出线程的一种方法,另外一种退出方法是调用pthread_exit()函数接口,这是结束函数的主动行为。pthread_exit()函数区别于exit()函数,调用exit()之后,所有该进程的线程都会被结束掉,因此,在线程中,利用pthread_exit()来替代进程中的exit()。

      由于一个进程中的数据段是共享的,因此通常在线程退出之后,退出线程所占的资源并不会随着线程的结束而得到释放。正如进程之间可以调用wait()函数来同步并释放资源一样,线程之间也有类似的机制,那就是pthread_join()函数。pthread_join()可以将当前线程挂起,等待线程的结束,该函数是一个阻塞函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待函数的资源会被释放。

      一般情况下,线程在其主体函数退出的时候会自动退出,但同时也可以因为接收到另一个线程发来的取消请求而强制退出。

总结上述,单个线程可以通过3种方式退出:

  • 线程可以简单地从线程入口函数中返回,返回值是线程的退出码;

  • 线程可以被同一进程中的其他线程取消(详见《SylixOS中pthread_cancel函数浅析》);

  • 线程显示地调用pthread_exit()函数。

     SylixOS兼容绝大部分POSIX接口函数,因此可以直接调用以下函数:

 

2.2  pthread_join()函数简析

函数原型:

#include <pthread.h>

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

  • 此函数成功返回0,失败返回错误号;

  • 参数thread是需要join的线程句柄;

  • 输出参数ppstatus是线程退出状态。

线程可以同步等待另一个线程退出,并获得其退出码。需要注意的是,同步等待的 目标线程必须处于合并状态,如图 2-1所示。

图 2-1线程同步等待

2.3  pthread_exit()函数简析

函数原型:

#include <pthread.h>

void pthread_exit(void * status);

  • 此函数无返回值;

  • 参数status是线程退出状态码。

    线程结束即线程显示或者隐式地调用pthread_exit()函数,status通常表示一个整数,

以指向一个更复杂的数据结构体,线程结束码将被另一个与该线程进行了合并的线程得到。

2.4  pthread_cancel()函数简析

函数原型:

#include <pthread.h>

int pthread_cancel(pthread_t thread);

  • 此函数成功返回0,失败返回错误号;

  • 参数thread是取消的线程句柄。

       pthread_cancel()函数和目标线程的取消动作是异步的,根据目标线程的设置不同,取消请求可能被忽略、立即执行或延迟处理。

 

3、  技术实现

3.1  pthread_join()函数实现

SylixOS中pthread_join()函数实现机制,如图 3-1所示:

图 3-1 pthread_join()函数实现流程

 

      代码中如果没有pthread_join(),主线程会很快结束从而使整个进程结束,从而使创建的线程没有机会开始执行就结束了。加入pthread_join()后,主线程会一直等待直到等待的线程结束自己才结束,使创建的线程有机会执行。所有线程都有一个线程号,也就是thread id,其类型为pthread_t,通过调用pthread_self()函数可以获得自身的线程号。

示例代码如图 3-2所示:

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

void *routine (void *arg)
{
    fprintf(stdout, "thread 1 return.\n");
    return ((void *)1);
}
void *routine1 (void *arg)
{
    fprintf(stdout, "thread 2 exit.\n");
    return ((void *)2);
}

int main (int argc, char **argv)
{
    pthread_t tid, tid1;
    int iRet;
    void *retval;

                                                     /* 创建routine线程*/
    iRet = pthread_create(&tid, NULL, routine, NULL);
    if (iRet != 0) {
        fprintf(stderr, "pthread create failed.\n");
        return (-1);
    }
                                                     /* 线程等待合并   */
   iRet = pthread_join(tid, &retval);
   if (iRet != 0) {
       fprintf(stderr, "pthread join thread 1 failed.\n");
       return (-1);
   }
   fprintf(stdout, "thread 1 return code: %ld\n", (long)retval);

                                                    /* 创建routine1线程*/
   iRet = pthread_create(&tid1, NULL, routine1, NULL);
   if (iRet != 0) {
       fprintf(stderr, "pthread create failed.\n");
       return (-1);
   }
                                                     /* 线程等待合并   */
   iRet = pthread_join(tid1, &retval);
   if (iRet != 0) {
       fprintf(stderr, "pthread join thread 2 failed.\n");
       return (-1);
   }
   fprintf(stdout, "thread 2 exit code: %ld\n", (long)retval);
   return (0);
}

图 3-2 pthread_join()函数示例

在SylixOS的shell下运行程序,结果如下:

# ./join_test
thread 1 return.
thread 1 return code: 1
thread 2 exit.
thread 2 exit code: 2

 

3.2  pthread_exit()函数实现

      用pthread_exit()来调用线程的返回值,用来退出线程,但是退出线程所占资源不会随便线程的终止而释放资源。

      pthread_exit()调用线程的返回值,可由其他函数如pthread_join()来检索获取。

     示例代码如图 3-3所示:

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

void thread_1 (void)
{
    int i = 0;

    for(i = 0; i <=6; i++){
        printf("This is a pthread_1.\n");

        if(i == 2){
            pthread_exit(0);                   /* 显示调用pthread_exit */
        }
        sleep(1);
    }
}

void thread_2 (void)
{
    int i;

    for(i = 0; i<3; i++){
        //printf("This is a pthread_2.\n");
        ;
    }
    pthread_exit(0);                           /* 显示调用pthread_exit */
}

int main (int argc, char **argv)
{
    pthread_t id_1,id_2;
    int iRet ;
                                                /* 创建线程1           */
    iRet = pthread_create(&id_1, NULL, (void *)thread_1, NULL);
    if(iRet != 0){
        printf("Create pthread_1 error\n");
        return -1;
    }
                                                /* 创建线程1           */
    iRet = pthread_create(&id_2, NULL, (void *)thread_2, NULL);
    if(iRet != 0){
        printf("Create pthread_2 error\n");
        return -1;
    }

    pthread_join(id_1, NULL);                   /* 等待线程结束        */
    pthread_join(id_2, NULL);
    return  (0);
}

 

图 3-3 pthread_exit()函数示例

在SylixOS的shell下运行程序,结果如下:

# ./pthread_exit

This is a pthread_1.

This is a pthread_2.

This is a pthread_2.

This is a pthread_2.

This is a pthread_1.

This is a pthread_1.

 

 

转载于:https://my.oschina.net/u/3026662/blog/832230

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值