线程如何让复杂的项目并行执行

为什么要有线程

  • 对于任何一个进程,默认有一个主线程,线程是负责执行二进制指令的,根据项目执行计划书,一行行的执行下去。
  • 进程比线程负责的多,除了执行指令之外,内存、文件系统都需要它来管理。

进程相当于一个项目,而线程就是为了完成项目需求,而建立的一个一个开发任务。

如果一个任务是可以拆解的,前后相关性没有很大关联,就可以并行执行。

比如有个开发任务,要开发200个页面,可以拆分成10个任务,每个任务负责10个页面,并行开发,完成之后再做一次整合,比一次开发200个页面快很多。

可以用多个进程实现并发吗? 不划算

  • 立项成本。创建进程占用资源太多
  • 沟通成本。进程之间的通信需要再不同的内存空间传来传去,无法共享

除了任务可以并行的需求外,还需要将前台和后台的任务隔离开,所以就需要创建额外的线程去处理后台的任务。

如何创建线程

进程的执行是需要项目执行计划书的,线程也有自己的项目执行计划书,就是一个函数,把需要执行的子任务放到这个函数里面。

比如:现在需要下载N个非常大的视频

解决思路:分拆成N个任务,分给N个线程各自去下载。

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
 
#define NUM_OF_TASKS 5
 
void *downloadfile(void *filename)
{
   printf("I am downloading the file %s!\n", (char *)filename);
   sleep(10);
   long downloadtime = rand()%100;
   printf("I finish downloading the file within %d minutes!\n", downloadtime);
   pthread_exit((void *)downloadtime);
}
 
int main(int argc, char *argv[])
{
   char files[NUM_OF_TASKS][20]={"file1.avi","file2.rmvb","file3.mp4","file4.wmv","file5.flv"};
   pthread_t threads[NUM_OF_TASKS];
   int rc;
   int t;
   int downloadtime;
 
   pthread_attr_t thread_attr;
   pthread_attr_init(&thread_attr);
   pthread_attr_setdetachstate(&thread_attr,PTHREAD_CREATE_JOINABLE);
 
   for(t=0;t<NUM_OF_TASKS;t++){
     printf("creating thread %d, please help me to download %s\n", t, files[t]);
     //参数分别为 线程对象、线程属性、线程运行函数、线程运行函数的参数
     rc = pthread_create(&threads[t], &thread_attr, downloadfile, (void *)files[t]);
     if (rc){
       printf("ERROR; return code from pthread_create() is %d\n", rc);
       exit(-1);
     }
   }
 
   pthread_attr_destroy(&thread_attr);
 
   for(t=0;t<NUM_OF_TASKS;t++){
     //获取这个线程退出时的返回值
     pthread_join(threads[t],(void**)&downloadtime);
     printf("Thread %d downloads the file %s in %d minutes.\n",t,files[t],downloadtime);
   }
 
   pthread_exit(NULL);
}

在这里插入图片描述

线程的数据

线程可以项目里的任务并行,但是也带来数据的问题

将线程访问的数据分为三类

  • 线程本地栈上的本地数据。
    • 函数执行过程中的局部变量,每个线程都有自己的栈空间,栈的大小可以通过unlimit -a来查看。
    • 为了避免线程之间的栈空间踩踏,线程栈之间还有有小块区域,用来隔离保护各自的栈空间,一个线程踏入隔离区,会引发段错误。
  • 进程里共享的全局变量。全局变量在一个进程里是共享的,如果两个线程一起修改,就会有问题,需要一种机制来保护他们。
  • 线程私有数据。
    • 通过int pthread_key_create(pthread_key_t *key, void (*destructor)(void*))创建一个key
    • key一旦被创建,所有线程都可以访问它,但各线程可根据自己的需要往key中填入不同的值,相当于同名而不同值的全局变量。
    • 通过int pthread_setspecific(pthread_key_t key, const void *value) 创建对应的value
    • 通过void *pthread_getspecific(pthread_key_t key) 获取key对应的value

线程退出的时候释放的时候 析构函数会释放value

数据的保护

Mutex

全称Mutual Exclusion,中文 互斥。在共享数据访问的时候,申请加锁,谁先拿到锁,就拿到了访问权限,其他人等锁。锁打开之后,重新竞争锁。

在这里插入图片描述

总结时刻

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值