线程

线程:进程中的一条执行路径。
在单CPU系统上,多个线程并发执行。
线程(thread):一个进程可以有多个线程,必须至少有一个线程(即主线程,主函数由主线程执行)
TID:线程ID
(一个程序做多个事情,一个线程相当于一个人肚子里的一条蛔虫)
一个进程中的所有线程共享该进程所有资源(空间共享,通信就直接简单了)。
进程产生后:操作系统会分配PID、私有地址空间
进程没有执行能力,进程是操作系统分配资源的基本单位。
每个线程都唯一对应一个线程函数,线程创建成功后会自动去调用自己的线程函数,线程函数执行完返回,该线程也就结束了。
进程与线程的区别和联系
1. 进程是操作系统分配资源的基本单位,没有执行能力。线程是操作系统分配CPU时间片的基本单位(调度的基本单元),具有执行能力。
2. 进程间通信很繁琐,但同一进程中的不同线程间通信很简单。
3. 线程属于进程,一个进程可以有多个线程,一个线程只属于某一个进程

(每次切换线程都要保存其他线程信息(保护现场))
不要创建太多线程,系统中线程太多会严重影响系统性能,因为系统会忙于线程调度处理。并且保存每个线程的现场信息(即当前运行状态和位置等)会消耗大量内存空间。
主线程和普通线程的区别:
1、 主线程由操作系统亲自创建,而普通线程由主线程直接或间接创建
2、 主线程只能有一个,而普通线程可以有多个或没有
3、 主线程结束进程就结束了,而普通线程结束对其他线程没有影响
相关函数 //进程编号 //状态(堆区栈区大小,优先级等)
 创建进程int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void (*start_routine) (void ), void *arg);
//线程函数 //传给线程的参数
 等待线程结束:int pthread_join(pthread_t thread, void **retval); //不关注时传NULL
//线程编号//线程结束信息(线程函数的返回值为void*)
成功返回0,错误放回错误号(不是-1)
 结束进程:pthread_exit(自杀),pthread_cancel(他杀,不建议这样操作)
void pthread_exit(void *retval);
//线程结束信息
int pthread_cancel (pthread_t thread); //只是一个请求,可用pthread_setcancelstate设置
用法示例:
 pthread_detach(pthread_self()); 给线程标标记,线程结束后操作系统会释放其资源。
不用等主线程释放,自己线程完了之后就可以释放资源。
创建线程后一定要使用(pthread_join或pthread_detach)释放资源
一般不建议强制结束线程,而是通过设置全局变量的值来给线程发信号结
束。

线程代码

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
void* thr_fun(void* arg);
int exit_flag=0;//
int main()//主线程与其他线程并发执行
{
    pthread_t tid;
    if(pthread_create(&tid,NULL,thr_fun,NULL)!=0)//创建一个线程
    {                                  
        fprintf(stderr,"pthread_create fail\n");
        exit(-1);
    }
    int a;
    for(a=0;a<5;a++)//主线程结束,其他线程也随即结束
    {
        printf("hello dj\n");
        sleep(1);
    }
    pthread_join(tid,NULL);//主线程阻塞,进入子线程,直到子线程结束
    return 0;
}
void* thr_fun(void* arg)//线程函数,多个线程时,执行顺序不确定
{
    int i;
    for(i=0;i<5;i++)
    {
        printf("你好\n");
        sleep(1);
    }
    pthread_exit((void*)3);//自行结束进程
    return NULL;
}

多线程代码

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define N 10000
void* thr_fun(void* arg);
int main()//分析思想:一个语句还没执行完,被打断,进入另一个线程
{
    int i;
    pthread_t tid[N];
    for(i=0;i<N;i++)//创建N个进程
    {   
        if(pthread_create(&tid[i],NULL,thr_fun,(void*)&i)!=0)//传地址
//      if(pthread_create(&tid[i],NULL,thr_fun,&i)!=0)//传地址//容易错误
//      if(pthread_create(&tid[i],NULL,thr_fun,(void*)i)!=0)//传值
            //因为int和指针都占四个字节,所以可以强转,否则截断  
        {                                    //给线程函数传参
            fprintf(stderr,"pthread_create\n");//通过参数区分不同线程
            exit(1);
        }
        usleep(1000);//阻塞主进程,以免i值被改变

    }
    for(i=0;i<N;i++)
    {
        pthread_join(tid[i],NULL);//同wait,两个作用,一是等子进程结束
    }                             //二是释放线程资源
    return 0;
}
void* thr_fun(void* arg)//多个线程共用一个线程函数
{
    pthread_detach(pthread_self());//pthread_self函数可获得线程ID
                                   //设置单身
    int p=*(int*)arg;
//  int* p=(int*)arg;//读主线程中i的值,而主线程一直在该i的值//读地址值
//  int p=(int)arg;//读值
    printf("%d号进程\n",p);

    return NULL;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章