线程——创建等待及退出

概述

  1. 进程与线程的不同
    进程:一个进程在同一时刻只做一件事情。
    进程是担当分配系统资源(CPU时间、内存等)的基本单位。
    进程是线程的容器。
    进程是程序(那些指令和数据)的真正运行实例。(程序和进程的区别)
    进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响。

    线程:在同一时刻做不止一件事,每个线程各自处理独立的任务。
    线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。
    线程有自己的堆栈和局部变量,但线程没有单独的地址空间,一个线程死掉就等于整个进程死掉。
    结论:
    多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,用线程比用进程更简易。

    多线程占资源少。在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这是一种"昂贵"的多任务工作方式。

    而运行于一个进程中的多个线程,它们彼此使用相同的地址空间,共享大部分数据,启动(线程间的切换),所花费的空间(时间)远远小于启动一个进程(进程间的切换)。

    进程间通信需要独立的数据空间,且只能通过通信的方式进行,这不仅费时且不方便。

    至于线程,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其它线程所用,这不仅快捷,而且方便。

    当然,数据的共享也带来其他一些问题,有的变量不能同时被两个线程所修改,有的子程序中声明为static的数据更有可能给多线程程序带来灾难性的打击,这些正是编写多线程程序时最需要注意的地方

  2. 线程的创建

#include <pthread.h>
int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
// 返回:若成功返回0,否则返回错误编号
// 参数pthread_t *restrict tidp:指针,创建的线程名。
// 参数const pthread_attr_t *restrict attr:属性,选择NULL
// 参数void *(*start_rtn)(void *):一个返回值为void*的API,(做一个结构体)
// 参数void *restrict arg:传递的参数(void*)

  1. 线程的退出
    单个线程可以通过以下三种方式退出,在不终止整个进程的情况下停止它的控制流:
      1)线程只是从启动例程中返回,返回值是线程的退出码。
      2)线程可以被同一进程中的其他线程取消。
      3)线程调用pthread_exit:
#include <pthread.h>
int pthread_exit(void *rval_ptr);
//参数rval_ptr:是一个无类型指针,与传给启动例程的单个参数类似。进程中的其他线程可以通过调用pthread_join函数访问到这个指针。
  1. 线程的等待

    调用这个函数的线程将一直阻塞,直到指定的线程调用pthread_exit。如果线程被取消,由rval_ptr指定的内存单元就置为PTHREAD_CANCELED。

如果对线程的返回值不感兴趣,可以把rval_ptr置为NULL。在这种情况下,调用pthread_join函数将等待指定的线程终止,但并不获得线程的终止状态

#include <pthread.h>
int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号
//参数pthread_t thread:需要等待的线程
//参数void **rval_ptr:二级指针,定义一个int型后在此函数内强转为(void**)&。
  1. 编程代码
#include <stdio.h>
#include <pthread.h>

//       int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);

void *func1(void *arg)
{
//      static int ret =10;
        static char *p="t1 is out!";//若不是static ,则函数调用一结束,这个值就会消失。
        printf("t1:%ld\n",(unsigned long)pthread_self());//打印线程的ID号
        printf("ti:param is %d\n",*((int *)arg));//对int型的指针取数据
//      pthread_exit((void*)&ret);
        pthread_exit((void*)p);
}
int main()
{
        int ret;
        int param=100;
        char *pret=NULL;
        pthread_t t1;
        ret=pthread_create(&t1,NULL,func1,(void*)&param);//指针指向t1,线程属性,启动线程需要调用哪些函数,传给函数的一个参数
        if(ret==0)
                {
                        printf("main:creat t1 success!\n");
                }
        printf("mian:%ld\n",(unsigned long)pthread_self());
        pthread_join(t1,(void **)&pret);//对谁等待,收回线程的退出状态指向**static** int ret。线程等待的意义是防止主线运行后立马退出,没有给其他线程运行的时间。
        printf("main:t1 ret:%s\n",pret);
        return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值