线程
1、相关描述
(1)进程的特点:
每一个进程的地址空间是相互独立的;
每一个进程都有一个task_struct任务结构体;
在进行进程切换时,需要不断刷新cache缓存,比较消耗资源;
为了减少cache刷新时的资源消耗,引入了轻量级进程 – 线程;
(2)线程特点:
同一个进程创建的多个线程,共用同一个进程的地址空间;
进程创建线程后,我们把原本进程也称为线程,称为主线程
(3)最小单位
进程被称为最小的资源分配单位
线程被称为最小的任务调度单位
(4)线程公共数据:
<1>用户名、用户组名
<2>静态数据、全局数据
<3>文件描述符—文件描述符是一个按顺序分配的最小非负整数,当用户打开或者新建一个文件时,系统会向当前进程返回一个最小的可用的文件描述
(5)私有数据:
<1>线程ID
<2>PC
<3>优先级、状态、属性
<4>堆栈
2、线程相关接口函数
pthread_create–创建线程
pthread_exit–结束线程
pthread_join–等待线程
(1)线程的创建
创建函数的细致描述:
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
参数:
thread:线程对象,一个线程对应一个线程对象
attr:线程属性,填NULL表示使用默认属性
start_routine:线程处理函数
arg:给线程处理函数start_routine传参,
如果线程处理函数没有参数,则填NULL;
Compile and link with -pthread.-->
在编译跟线程操作相关的程序时,需要链接线程库
线程库名--pthread
(2)结束线程
#include <pthread.h>
void pthread_exit(void *retval);
参数:
retval:线程结束信息,由pthread_join等待接收,如果不想返回信息,则填NULL
Compile and link with -pthread.
(3)等待线程
#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
等待线程一般在主线程中调用
Compile and link with -pthread.
(4)实例
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
void *func();
void *func1();
int main(int argc, char *argv[])
{
pthread_t thread1,thread2;//定义两个线程对象
void *result1=NULL;
void *result2=NULL;
int d=123;
int ret1=pthread_create(&thread1,NULL,func,NULL);//创建线程
if(ret1<0)
{
perror("pthread");//错误就输出错误原因
exit(-1);//并结束进程
}
ret1=pthread_create(&thread2,NULL,func1,NULL);//创建线程
if(ret1<0)
{
perror("pthread");
exit(-1);
}
while(1)
{
printf("----d=%d\n",d);//只是方便观察,可不要
sleep(1);
}
pthread_join(thread1,&result1);//等待线程,
printf("%s\n",(char *)result1);//并打印线程号,可不打印,上面&result改为NULL
pthread_join(thread2,&result2);
printf("%s\n",(char *)result2);
return 0;
}
void *func(void *arg)//线程1函数
{
int n=3;
while(n--)
{
printf("bbbbbbb\n");
sleep(1);
}
pthread_exit("i am thread1");//线程的结束,并输出,可不打印
}
void *func1()//线程2函数
{
int n=5;
while(n--)
{
printf("cccccc\n");
sleep(1);
}
pthread_exit("i am thread2");
}
代码运行:
注:编译的时候要链接文件’-pthread’