linux系统编程—线程的相关概念、创建、等待和退出

线程概念

线程是进程的一部分,描述指令流执行状态。它是进程中的指令执行流的最小单位,是CPU调度的基本单位。线程可以看成是轻量级进程,是操作系统进行调度的最小单位。一个线程是一个任务(一个程序段)的一次执行过程。线程不占有内存空间,它包括在进程的内存空间中。在同一个进程内,多个线程共享进程的资源。一个进程至少有一个线程。

线程状态

操作系统创建线程时,线程处于创建态,CPU调度线程时,线程处于运行态,此时其它已创建的或者时间片到的线程就处于就绪态,当然还有些线程在进行磁盘、网络等IO时就处于阻塞态,操作系统销毁线程时,线程就处于终止态。另外,线程还具有静止就绪态和静止阻塞态,处于这两种状态,说明这个线程被操作系统挂起了,操作系统挂起线程,是为了观察和分析线程状态。

线程特点

小开销:和进程相比,它是一种非常"节俭"的多任务操作方式。我们知道,在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这是一种"昂贵"的多任务工作方式。而运行于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间。

通信方便:对不同进程来说,它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行,这种方式不仅费时,而且很不方便。线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其它线程所用,这不仅快捷,而且方便。

并发执行:在一个进程中的多个线程之间,可以并发执行,甚至允许在一个进程中所有线程都能并发执行;同样,不同进程中的线程也能并发执行,充分利用和发挥了处理机与外围设备并行工作的能力。

资源共享:在同一进程中的各个线程,都可以共享该进程所拥有的资源,这首先表现在:所有线程都具有相同的地址空间(进程的地址空间),这意味着,线程可以访问该地址空间的每一个虚地址;此外,还可以访问进程所拥有的已打开文件、定时器、信号量机构等。由于同一个进程内的线程共享内存和文件,所以线程之间互相通信不必调用内核。当然,数据的共享也带来其他一些问题,有的变量不能同时被两个线程所修改,有的子程序中声明为static的数据更有可能给多线程程序带来灾难性的打击,这些正是编写多线程程序时最需要注意的地方。

pthread_create()线程创建函数

#include <pthread.h>

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

成功时返回零,错误时返回错误码

参数一:为指向线程标识符的指针

参数二:用来设置线程属性,通常为NULL

参数三:函执行函数指针,该函数运行结束,则线程结束

参数四:传入线程执行函数的参数

pthread_join()线程等待退出函数

#include <pthread.h>

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

成功时返回零,错误时返回错误码

参数一:thread线程标识符

参数二:存储线程结束状态

pthread_exit()线程退出函数

#include <pthread.h>

void pthread_exit(void *retval);

返回值: 调用现成的返回值,可用其它函数pthread_join 来获取

参数retval为无类型指针,内容传给pthread_join函数的第二个参数

其他api:

pthread_self():获取自身线程id

int pthread_detach(pthread_t thread):实现线程分离,不再受主线程管理,由系统接任。线程结束后,其退出状态不由其他线程获取,而直接自己自动释放

代码示例

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


void *func1(void *arg)
{
    static char *p = "t1 is run out";//必须定义static 

    printf("t1 id:%ld\n",(unsigned long)pthread_self());//打印线程func1线程id
    printf("t1:param is %d\n",*((int *)arg));//打印参数arg

    pthread_exit((void *)p);//线程退出
}

int main()
{
    int param = 100;
    pthread_t t1;

    char *pret = NULL;//储存进程结束状态

    if( pthread_create(&t1, NULL, func1,(void *)&param) == 0)
    {
        printf("main:创造t1成功\n");
    }

    printf("main id:%ld\n",(unsigned long)pthread_self());//打印main线程id

    pthread_join(t1,(void **)&pret);//等待线程退出

    printf("main: t1退出: %s\n",pret);//打印线程结束状态

    return 0;
}

编译运行

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值