Linux下线程的概念和使用

一. 概念
  首先Linux并不存在真正的线程,Linux的线程是使用进程模拟的。当我们需要在一个进程中同时运行多个执行流时,我们并不可以开辟多个进程执行我们的操作(32位机器里每个进程认为它 独享 4G的内存资源),此时便引入了线程,例如当我们既需要下载内容,又需要浏览网页时,此时多线程便起了作用。线程是承担调度的基本单位,一个进程可拥有多个线程,它的执行力度比进程更加细致,线程资源共享。
二. 特点
  由于同一进程的多个线程共享同一地址空间,所以代码段,数据段是共享的,如果定义一个函数(存储在代码段),各线程都可以进行调用,如果定义个全局变量(存储在数据段),在各线程中都可以访问到,除此之外,各线程还共享以下进程资源和环境:
1.文件描述符表
2.每种信号的处理方式(SIG_IGN,SIG_DFL,用户自定义)
3.当前工作目录
4.用户id和组id
但有些资源是线程独享的:
1.线程id
2.上下文,包括各种寄存器的值,程序计数器和栈指针
3.栈空间
4.errno变量
5.信号屏蔽字
6.调度优先级
三. 线程的简单实用
1.创建线程

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

  返回值:成功返回0,失败返回错误号。在一个线程中调pthread_create()创建新的线程后,当前线程从pthread_create()返回继续往下执行,新的线程所执行的代码由我们传给pthread_create的函数指针start_routine决定。
  thread参数传入线程的id,void ( star_routine)(void )由用户进行撰写。
2.线程终止
  void pthread_exit(void *retval)函数用于进程终止,传入一个id,调用exit()的话,主进程会终止。终止线程由三种方法:
1).从线程函数return。这种方法法对主线程不适用,从main函数return相当于调用exit。
2).一个线程可以调用pthread_cancel终止同一进程中的另一个线程。
3).线程可以调pthread_exit终自己。
  retval是void *类型,其它线程可以调pthread_join获得这个指针。
3.线程等待
  int pthread_join(pthread_t thread,void **retval);成功返回0,失败返回错误号。 线程的等待是以阻塞式等待,线程不等待会产生内存泄露(类似进程的僵尸进程)
4.进程取消
  在合理范围内,线程可以自我或者被别人取消。取消后返回PTHREAD_CANCELED(它被定义为(void *)-1),取消调用函数pthread_cancel(id);
5.线程分离
  在任何一个时间点上线程是可结合的(joinable)或者是分离的(detached)。一个可结合的线程能够被其他线程收回其资源和杀死。在被其他线程回收之前,它的存储器资源(例如栈)是不释放的。相反一个分离的线程是不能被其他线程回收或杀死的,它的存储器资源在它终时时由系统自动释放。
  默认情况一个线程是可结合的,每一个可结合的线程都应该被显性的回收,既调用pthread_join()函数,分离调用函数pthread_detach。分离的这个函数是非阻塞的,可以立即返回。但为什么要分离呢?因为主进程在处理线程时,要处理不止一个,而每一个都需要被等待,然而join是阻塞式的,这样的话就只能处理一个线程,所以要加入分离,这样就可以处理多个线程。调用pthread_detach()后,这些子进程的状态会被设置为分离的,该线程运行结束会自动释放所有资源。
  下面为测试代码:

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

void* thread1()
{
    pthread_detach(pthread_self());//分离后仍可被等待
    printf("pid is: %d, tid is: %d\n", getpid(),pthread_self());
    return (void*)1;
}
int main()
{
    pthread_t tid;
    void *ret;
    int err = pthread_create(&tid, NULL, thread1, NULL);
    if (err != 0)
    {
        perror("pthread_create\n");
        return err;
    }
    //如果直接运行等待代码,一般会等待成功,返回1
    //如果在等待之前加入取消。等待错误,返回-1
    //  pthread_cancel(tid);
    //线程可以自我取消也可以被取消,线程终止
    //调用pthread_exit(tid);和取消同样用法。
    int tmp = pthread_join(tid, &ret);
    if (tmp == 0)
    {
        printf("wait success\n");
    }
    else
    {
        printf("wait failed\n");
    }
    printf(" pid is: %d, tid is: %d\n", getpid(),pthread_self());
    sleep(1);
    return 0;
}
  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值