linux多线程----基本概念

来源:互联网 发布:淘宝批发货源网哪个好 编辑:程序博客网 时间:2024/06/06 20:16

线程----轻量级进程,由于线程具有高效性和可操作性,在大型程序开发中运用的非常广泛,进程是系统中程序执行和资源分配的基本单位,每个进程拥有自己的数据段,代码段,堆栈段,这就造成了进程进行切换时需要有比较复杂的上下文切换等动作,为了减少处理器的空转时间,支持多处理器以及减少上下文切换开销,由此就演化出了线程这一概念,他是进程内独立的一条运行路线,是处理器调度的最小单元,线程可以对进程的内存空间和资源进行访问,并与同一进程中的其他线程共享,所以线程的上下文切换比创建进程小很多

       和进程一样线程也将相关的执行状态和存储变量放在线程控制表内,一个进程可以有多个线程,也就是有多个线程控制表和堆栈寄存器,但却共享一个用户地址空间,线程共享进程的资源和地址空间,所以线程的推出会影响其他的线程,所以多线程的同步是非常重要的,进程与线程的关系如下:

线程的分类:

线程可以分为用户级线程和核心级线程两种

(1)用户级线程

用户级线程线程解决的是上下文切换的问题,他的调度算法和调度工程全部是由用户自己解决,运行不需要内核的支持,操作系统会提供一个用户空间的线程库,线程库提供了线程的创建,调度和撤销的功能,内核仅对进程进行管理。如果一个线程调用了一个阻塞的系统调用,则该进程的其他线程也会被阻塞住。用户级线程的缺点是:一个进程中的多个线程调度中无法发挥多处理器的优势。

(2)轻量级线程:

轻量级线程是内核支持的用户线程,是内核线程的一种抽象对象,每个进程拥有一个或多个轻量级线程,每个轻量级线程分别绑定在一个内核线程上

(3)内核线程

这种线程允许不同进程中的线程按照同一相对优先调度算法进行调度,这样可以发挥多处理器的并发优势,现在多数操作系统都采用用户级线程与核心级线程并存的方法,一个用户级线程可以对应一个或多个核心级线程,也就是一对一或一对多的关系。这样既可以满足多处理器的需求,也可以最大限度的减少调度开销,使用线程能够大大的加快上下文的切换速度而且能够节省很多资源,但因为在用户态和内核态都需要进行调度管理,所以会增加实现的复杂度和引起优先级翻转的可能性,一个多进程的程序的同步设计和调试也会增加程序的实现的难度。

这里说的线程的相关操作都是用户空间的线程操作,在linux中pthread线程库是一套通用的线程库,是由POSIX提供的,具有很好的移植性

线程使用的函数说明:

创建线程其实就是确定调用线程函数的入口点,创建线程的通常函数是pthread_create(),创建线程之后就开始运行线程函数,线程函数退出之后,这个线程也就退出了这是一种线程退出的方法,线程退出也可以使用pthread_exit(),这是线程的主动行为,不能使用exit()因为exit()是进出退出的函数。

      一个进程中的多个线程是共享数据段的,所以线程退出之后,退出线程所占用的资源并不会随着线程的终止而得到释放,正如进程可以使用wait()系统同步终止并释放资源一样,线程也有类似的机制,线程使用pthread_join(),pthread_join()能够将当前进程挂起来等待线程的结束,这是个阻塞函数,当函数返回时被等待线程的资源也就被释放了。

pthread_exit()是自身终止线程,有时我们需要终止别的线程,此时需要pthread_cancel()函数,被取消通过pthread_setcancel()和pthread_setcanceltype()设置自己的取消状态,例如当收到命令是忽略还是接受,接受是马上终止还是等待某个函数的调用。

pthread_create()函数格式:

pthread_exit()函数语法要点:

pthread_join()语法要点:

pthread_cancel()函数语法如下:

下面是个线程的例子:

#include <stdio.h>#include <stdlib.h>#include <pthread.h>#define THREAD_NUMBER 3//线程个数#define REPEAT_NUMBER 5#define DELAY_TIME_LEVELS 10.0void *thrd_func(void *arg)//线程函数{    int thrd_num = (int)arg ;    int delay_time = 0 ;    int count = 0 ;    printf("thread %d is starting\n", thrd_num) ;    for (count  = 0; count < REPEAT_NUMBER; count++)//每个线程完成五次任务    {        delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX)) + 1;//产生随机时间        sleep(delay_time) ;        printf("\tThread %d:job %d delay = %d\n",                    thrd_num, count, delay_time) ;    }    printf("thread %d finished\n", thrd_num) ;    pthread_exit(NULL) ;}int main(){    pthread_t thread[THREAD_NUMBER] ;    int no = 0, res ;    void *thrd_ret ;    srand(time(NULL)) ;//产生随机种子    for(no = 0; no < THREAD_NUMBER; no++)    {        res = pthread_create(&thread[no], NULL, thrd_func, (void *)no) ;//创建线程        if (res != 0)        {            printf("create thread %d failed\n", no) ;            exit(res) ;        }    }    printf("create threads success\n waiting for threads to finish...\n") ;    for (no = 0; no < THREAD_NUMBER; no++)    {        res = pthread_join(thread[no], &thrd_ret) ;//等待线程结束        if (!res)        {            printf("thread %d joined\n", no) ;        }        else        {            printf("thread %d joined failed", no) ;        }    }    exit(0) ;}

这里程序中创建了三个线程,每个线程执行五次循环,每次循环随机的等待1~10秒。

编译的时候会出现

undefined reference to 'pthread_create'
undefined reference to 'pthread_join'

这是因为pthread不是linux默认的库,连接需要链接静态库libpthread.a库,所以编译使用   gcc thread.c -o thread -lpthread命令,头文件需要加入#include<pthread.h>

http://blog.csdn.net/llqkk/article/details/2854558

程序执行结果如下:

可以看出三个线程并行,独立的执行直到每个线程结束。


     





原创粉丝点击