线程(一)

1、线程的概念:
线程是进程内部的一条执行序列(执行流),每个进程至少有一条执行序列,即每个进程
至少有一个线程。进程可以通过线程库创建N个线程,这些新创建的线程称之为函数线程,main函数代表的线程为主线程。

2、线程与进程的区别:
  (1) 进程是资源分配的最小单位,线程是CPU 调度的最小单位;
  (2) 线程是轻量级的进程;
  (3) 两者的管理方式不同,进程由PCB(进程控制块)管理,线程由线程结构管理;
  (4) 线程有用户态和内核态的实现方式的选择(下面会详细介绍两种方式),因为线程
      是进程内部的东西,存在由进程直接管理线程的可能性;而进程就没有实现方式的
      问题,因为进程是在CPU上实现并发,而CPU由操作系统管理,因此进程的实现只能
      由操作系统来完成。

3、线程的优缺点
      优点:
      (1) 可以将一个复杂的应用程序分解成几个线程来执行,从而改善程序的性能,并且
          有时会让程序看起来好像在同时做两件事,比如说,在编辑文档的同时对文档中
          的单词个数进行实时统计,简单的来说就是一个线程负责处理用户的输入并执行
          文本编辑工作,另一个线程则不断刷新单词计数变量,第一个线程通过共享这个
          计数变量让用户了解自己的工作进度。      
      (2) 线程之间的切换需要操作系统做的工作要比进程之间的切换少得多,因此多个线程
          需要的资源要远小于多个进程。
       缺点:
       (1) 线程之间的交互非常难控制,因此多线程程序的调试会比较难;
       (2) 多处理线程的程序需要拥有多个处理器核来支持,如果放在一台单处理器上
             并不一定会运行的更快。
             
4、线程实现的三种方式
(1) 内核态:
            由操作系统来管理线程,即将线程控制块放到操作系统内核空间,这样做的
      好处有用户可以编程保持简单,用户程序员不需要管理线程的调度,这些都有
      操作系统来监控;当然也有坏处,首先线程每次切换都要陷入内核由操作系统
      来完成,造成效率较低,其次如果内核空间满了的话将无法成功创建线程。          
(2) 用户态:
            由进程自己来管理线程,即由用户自己来完成线程的切换及信息管理,操作系
      统不需要知道线程的存在,但需要用户自己写一个执行系统作调度器,这也是一个
      线程,所以没有能力强行夺走控制权去中断一个正在执行的线程,这会造成一个线
      程阻塞则这个进程也被阻塞,同时编程也会比较复杂;优点是灵活性强,线程切换
      快。
(3) 混合模式:
            中和内核态和用户态的缺陷,结合二者有了混合模式。在分配线程时,将需要
      执行阻塞操作的线程设为内核态线程,而将不会执行阻塞操作的线程设为用户态线
      程。用户态的执行系统负责进程内部线程在非阻塞时的切换,内核态的操作系统负
      责阻塞线程的切换,即同时实现内核态和用户态线程管理。每个内核态线程可以服务
      一个或多个用户态线程。
      
5、线程的创建

#include<pthread.h>
int pthread_create(pthread_t *id,pthread_attr_t *attr,
                   void*(*fun)(void),void* arg);

id:函数成功返回时,id指向创建新线程的线程ID;
attr:定制不同的线程属性,一般设置为NULL;
fun:返回值为void*的函数指针,这里不是函数调用,而是创建函数线程;
arg:如果向fun函数传递的参数不止一个,将这些参数放到一个结构体,arg则指向这个
      结构体的地址;
注意:
(1) 包含线程创建函数的源代码要想生成可执行文件,在编译时必须链接动态库:
     gcc -o pthread pthread.c -lpthread
(2) 创建出来的函数进程不同于函数调用,函数调用是这条执行流的一部分,函数线程
     是创建出一条独立的执行序列,它与主线程同时执行,并且与主线程的pid相同;
(3) 主线程与函数线程的区别:主线程是进程的切入点;
(4) 线程结束不以exit(0)结束,以int pthread_exit(void*)结束,参数可以设置为线程结束
     状态;函数线程创建后与主线程同时执行,主线程以pthread_exit函数结束,即进程结
     束,所有的函数线程都将结束;
(5) 等待线程结束可以用:
     int pthread_join(pthread_t id,void*);
     可以获取到等待的线程通过pthread_exit函数设置的结束状态信息。

练习:创建函数线程,主线程完成对数组元素的排序,函数线程完成简单的打印.

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

void*  pthread_fun()
{
    int i;
    for(i=0;i<5;i++)
    {
        printf("hello\n");
    }
    pthread_exit("world\n");
}

int  main()
{
    pthread_t id;
    int res = pthread_create(&id,NULL,pthread_fun,NULL);
    assert(res == 0);

    int arr[6] = {2,5,3,7,9,8};
    int i;
    int j;
    int tmp ;
    for(i=0;i<6;i++)
    {
        for(j=i;j<6;j++)
        {
            if(arr[i]>arr[j])
            {
                tmp = arr[i];
                arr[i] = arr[j];
                arr[j] = tmp;
            }
        }
    }
    for(i=0;i<6;i++)
    {
        printf("%d  ",arr[i]);
    }
    printf("\n"); 
    pthread_exit("over\n");
    return 0;
}

结果

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值