线程的概念以及线程在Linux上的实现

线程的概念

  线程是进程内部的一条执行路径(执行序列或执行流),一个进程可以包含多个线程。将main函数的线程称之为主线程,其他线程称之为函数线程。
函数线程的主要构造如下:

void *fun(void *arg);
int main()
{
	pthread_create(fun);//只是给定一个函数地址,来指定创建的线程从哪个函数开始执行
}
线程的实现方式(windows下)

用户级线程
  由应用程序所支持的线程实现, 内核意识不到用户级线程的实现.。
  优点:灵活,内核不需要知道线程的存在;切换效率高,因为不需要陷入内核;不用修改操作系统,实现简单。
  缺点:如果一个线程阻塞,则会造成整个进程的阻塞;用户程序相对复杂一些。
内核级线程
  优点:用户程序比较简单;一个线程阻塞,可以很从容的切换到另一个线程。
  缺点:切换效率较低,每次切换都需要陷入内核态;占用内核稀缺的内存资源。

混合级线程
  既存在用户级线程,也存在内核级线程。

Linux系统的线程实现方式

  Linux系统从内核的角度来看,并没有线程这个概念。Linux把所有的线程都当作进程来实现。内核没有准备特别的调度算法或是定义特别的数据结构来表征线程。线程仅仅被视为一个与其他进程共享某些资源的进程。

线程与进程的区别

  进程是资源分配的最小单位,线程是CPU调度的最小单位(CPU执行的最小单位是指令);
  进程有自己独立的地址空间,线程共享进程中的地址空间;
  进程的创建消耗资源大,线程的创建相对较小;
  进程的切换开销大,线程的切换开销相对较小;

Linux系统上线程库的使用
int pthread_create(pthread_t *id,pthread_attr_t *attr,void *(*pthread_fun)(void*),void *arg);//成功返回0,失败返回错误码

  id : 传递pthread_t类型变量的地址,用于返回创建的线程 id ; attr : 设置线程的属性,默认属性直接传递NULL; pthread_fun:线程函数的地址(用户自己实现的函数); arg:传递给线程函数的参数。
  给线程函数传递的参数 void* ,可以传递一个小于等于4字节(32位平台上)的值类型,或者传递一个地址。(函数线程和传递参数的线程共享传递的变量)
  线程之间除了共享地址空间,还共享进程的.text 段、.data、.heap 、.stack 以及内核(文件描述符)。

Linux线程实现的例子
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<pthread.h>

void *fun(void*);

int main()
{
   int a=10;
   pthread_t id;
   int res=pthread_create(&id,NULL,fun,(void*)a);
   assert(res==0);
   
   a=20;
   int i=0;
   for(;i<5;++i)
   {
       printf("main running\n");
       sleep(1);
   }
   pthread_exit(NULL);//结束一个线程,并设置线程结束的一些信息
}
void *fun(void *arg)
{
    int b=(int)arg;
    printf("b=%d\n",b);//传递的是a的值,因此b依然等于10,而不是20;若传a的地址,则b=20
    int i=0;
    for(;i<8;++i)
    {
        printf("fun running\n");
        sleep(1);
    }
}

注意:使用gcc编译上述代码是,后面要加 -lpthread
执行结果如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值