Linux线程的使用策略

线程的基本概念

线程是进程内部的一条执行序列。进程内部至少有一条执行线程,即就是main函数的执行体。进程内部可以有多条线程,main函数的线程称为主线程,包括其执行过程中调用的其他的函数,而其他线程称为函数线程,函数线程是由主线程通过系统调用函数创建的。

线程与进程的区别

1、进程是资源分配的最小单位,线程是系统调度(执行)的最小单位。
2、线程切换比进程切换消耗小。
3 、进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮。

线程的分类

1、用户级:在用户空间是多线程的,内核只识别进程整体。线程创建、管理、销毁都是由用户空间负责,用户通过调用库函数来完成。用户态和内核态是n:1的关系。
2、内核级:线程的创建、控制、销毁都是由内核实现的,每个线程对内核都是可见的。用户态和内核态是n:n的关系。
3、组合模型:一部分是用户级,一部分是内核级。介于内核级和用户级之间,用户态创建多个线程,内核看到的也是多个,是n:m的对应关系。
线程的分类

线程的使用

1、线程的创建
头文件:#include<pthread.h>
库函数:

int pthread_create(pthread_t *id,pthread_attr_t *attr,void *(*pthread_fun)(void *),void *arg);

id:线程的编号,有系统自动填充;
attr:线程属性;
pthread_fun:线程创建以后所调用的函数地址
arg:传递给函数线程的参数。
总结
(1)pthread_create函数是库函数,编译的时候必须加载其动态库libpthread.so。
(2)线程函数和写一个普通函数没有明显差别,只不过在主线程不会调用线程函数,而是在创建线程的时候指定函数线程执行的代码入口地址(即就是函数的入口地址)。称主函数为主执行序列,函数的执行为函数线程的执行流。
(3)主线程和函数线程同时执行,一个进程同时执行多个任务。
2、 线程的结束
exit是结束进程的函数,主线程要结束但是函数线程还在运行,我们主线程就不能调用exit结束,必须使用pthread_exit(void *reval);
线程等待其他线程结束

int pthread_join(pthread_t id,void **p);

作用:获取指定线程有由pthread_exit设置的退出信息。
特性:pthread_join函数会阻塞直到等待的线程退出(类比进程控制中的wait函数)。
3、线程间数据共享
(1)全局变量 共享
(2)局部变量(栈区) 不共享
(3)堆区 共享
(4)文件 共享 同一个进程的线程,使用一个PCB,只要线程能线程能拿到打开文件的文件描述符,就可以通过文件描述符操作文件。
4、代码举例
头文件

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

例1:pthread1.c

void * fun_pthread1(void *arg)
{
    sleep(1);
    pthread_t pid = *(pthread_t *)arg;//获取线程2的id
    pthread_join(pid,NULL);//等待线程2结束
    int i,j;
    for(i=2;i<=100;i++)//打印100以内的素数
    {
        int count = 0;
        for(j=1;j<=100;j++)
        {
            if(i%j==0)
            {
                count++;
            }
        }
        if(count == 2)
        {
            printf("%d ",i);
        }
    }
    printf("\n");
}

void * fun_pthread2(void *arg)//对数组元素进行排序,并打印结果
{   
    int arr[] = {18,23,9,56,90,76,81,44,38,62};
    int len = sizeof(arr)/sizeof(arr[0]);
    int i,j;
    for(i=0;i<len-1;i++)
    {
        int min_index = i;
        for(j=i+1;j<len;j++)
        {
            if(arr[j] < arr[min_index])
            {
                min_index = j;
            }
        }
        int temp = arr[min_index];
        arr[min_index] = arr[i];
        arr[i] = temp;
    }

    for(i=0;i<len;i++)
    {
        printf("%d ",arr[i]);
    }
    printf("\n");
    pthread_exit("sort over");
}

int main()
{
    printf("Main Thread run\n");
    pthread_t id1,id2;
    pthread_create(&id1,NULL,fun_pthread1,(void *)&id2);//传递另一个线程的id
    pthread_create(&id2,NULL,fun_pthread2,NULL);

    int *p;
    pthread_join(id1,NULL);//等待线程1结束
//  pthread_join(id2,(void **)&p);//等待线程2结束,并获取线程退出时携带的数据
//  printf("%s\n",p);//打印线程2退出时携带的数据
    sleep(5);
    return 0;   
}

运行结果
pthread1.c线程2退出时携带数据

pthread1.c线程1等待线程2运行结束后执行
例2:pthread2.c

//函数线程 
void * fun(void *arg)
{
    printf("Child Thread Run\n");
    int j;
    for(j=0;j<5;j++)
    {
        printf("child:j = %d\n",j);
        sleep(2);
    }
    //打印主线程传递的参数 
    printf("a = %d\n",*(int *)arg);
}

int main()
{
    printf("Main Thread Run\n");
    pthread_t id;
    int a = 10;
    int val = pthread_create(&id,NULL,fun,(void *)&a);
    assert(val == 0);//若创建线程成功,则返回0
    a = 20;
    int i;
    for(i=0;i<3;i++)
    {
        printf("main:i = %d\n",i);
        sleep(1);
    }
    pthread_exit(NULL);//线程结束 
    return 0;
}

运行结果
pthread2.c

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值