设为首页 加入收藏

TOP

线程控制(一)
2019-09-14 00:52:38 】 浏览:79
Tags:线程 控制

1. 线程与进程

线程的概念

线程是进程内相对独立的一个执行流,是进程内的一个执行单元,是操作系统中一个可调度的实体。

深入理解进程和线程

  • 在现代操作系统中,资源分配的基本单位是进程,而CPU调度执行的基本单位是线程
  • 进程不是调度单元,线程是进程使用CPU资源的基本单位
  • 进程有独立的地址空间,进程中可以存在多个线程共享进程资源
  • 线程不能脱离进程单独存在,只能依附于进程运行
  • 线程可以在不影响进程的情况下终止,但反之则不然

2. 多线程

什么是多线程

多线程,是指从软件或硬件层面上实现多个线程并发执行的技术。

  • 从软件层面看,一个进程中可以有多个线程,该程序也可以称之为多线程程序;
  • 从硬件层面看,多核处理器能够支持在同一时间执行多个线程。

实际上,对于单核处理器,即使软件编写为多线程模型,同一时间也只能执行一个线程,但这并不代表此时多线程就没有意义,因为处理器的数量不会影响程序结构,那么多线程编程模型在程序结构上到底有哪些好处呢?

多线程模型的好处

  • 通过为每种事件类型分配单独的处理线程,可以简化异步事件处理代码
  • 可以直接共享进程的数据资源
  • 将复杂问题分解为相互独立的任务,可以交叉进行,提高程序吞吐量
  • 通过把处理用户输入输出的部分和其他部分分开,可以改善交互式程序响应时间

3. 线程标识

  • 线程ID(Thread ID)是线程的唯一标识
  • 线程ID只有在它所属的进程上下文中才有意义
  • 线程ID类型为pthread_t,可能实现为unsigned long或结构体,依系统而定
  • 线程可以调用pthread_self获得自身线程ID
  • 可移植的程序应该调用pthread_equal来比较两个线程的ID
#include <pthread.h>

pthread_t pthread_self();  //返回调用线程的线程ID
int pthread_equal(pthread_t tid1, pthread_t tid2); //相等返回非0数值,否则返回0

4. 线程创建

函数原型

任意线程可以通过调用pthread_create创建新线程,start_routine为新线程的启动例程,创建成功后,新线程和调用线程谁先运行是不确定的。

//成功返回0,失败返回错误编号
int pthread_create(pthread_t *tid, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg); 

参数说明

  • pthread_create成功返回后,tid指向内存即为新线程ID
  • attr用于定制线程属性,若使用默认属性则传NULL
  • start_routine是线程启动例程
  • arg是start_routine的参数,若参数不止一个,就把这些参数放到一个结构中,再把该结构的地址作为arg传入

使用示例-打印线程ID

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

pthread_t tid;

void printf_tid(const char *s)
{
    pid_t     pid = getpid();
    pthread_t tid = pthread_self();    
       
    printf("%s pid = %d, tid = %lu(0x%lx)\n", s, pid, tid, tid);
}

void *pthread_start(void *arg)
{
    printf_tid("new thread:  "); //新线程用pthread_self()获取自身ID,是因为新线程执行时pthread_create()可能还未返回,tid还未初始化完成
}

int main()
{     
    pthread_create(&tid, NULL, pthread_start, NULL);
    sleep(1); //调用线程休眠1S,让新线程先执行
    printf_tid("main thread: ");
    
    return 0;
}

注意:使用pthread的代码在编译时需要指定链接-lpthread

5. 线程终止

在不影响整个进程的情况下,单个线程有三种终止方式:

  • 在线程启动例程中调用return返回
  • 在线程启动例程中调用pthread_exit退出
  • 被进程中的其他线程取消
void pthread_exit(void *value_ptr);

value_ptr是一个无类型指针,进程中的其他线程可以调用pthread_join访问到这个指针。

6. 线程等待

函数原型

int pthread_join(pthread_t tid, void **value_ptr); //成功返回0,失败返回错误编号

调用线程将一直阻塞,直到等待的线程以上述三种方式终止。

参数说明

  • tid表示等待的线程ID
  • value_ptr用于保存线程的退出状态
  • 如果线程以return或pthread_exit方式终止,value_ptr指向内存就被设置为return或pthread_exit的参数
  • 如果线程被取消,value_ptr指向内存就被设置为PTHREAD_CANCELED
  • 如果不关心线程的返回值,就给value_ptr传NULL

使用示例-获得线程返回值

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

void *thread1_start(void *arg)
{
    int ret = 0;
    return ((void *)ret);
}

void *thread2_start(void *arg)
{
    char *ret = "thread 2 exit";
    pthread_exit(ret);
}

int main()
{     
    pthread_t tid1;
    pthread_t tid2;
    void *ret;
    
    pthread_create(&tid1, NULL, thread1_start, NULL);
    pthread_create(&tid2, NULL, thread2_start, NULL);
    
    pthread_join(tid1, &ret);
    printf("thread 1: %d\n", (int)ret); 
    
    pthread_join(tid2, &ret);
    printf("thread 2: %s\n", (char *)ret);
    
    return 0;
}

7. 线程分离

在默认情况下,线程的终止状态会一直保存到对该线程调用pthread_join;但是,如果线程已经

首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇RedHat Linux-配置YUM仓库 下一篇解锁HMC8及HMC9的root用户

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目