文章目录
- 一、线程和进程?
- 二、线程初识
- 2.1 线程属性
- 2.2 线程的调度策略
- 2.3 线程的优先级
- 2.3 线程实验
一、线程和进程?
我们经常描述进程(process)和线程(thread): 进程是资源管理的最小单位,线程是程序执行的最小单位。从进程演化出线程,主要是因为进程拥有数据段、代码段、堆栈段,导致进程切换上下文开销大。在进程中创建一个新线程时,新的执行线程将拥有自己的栈, 但与它的创建者共享全局变量、文件描述符、信号处理函数和当前目录状态。 也就是说,它只使用当前进程的资源,而不是产生当前进程的副本。
二、线程初识
2.1 线程属性
线程属性值有一个分离状态决定一个线程以什么样的方式来终止自己。一个可结合的线程能够被其他线程收回其资源和杀死;在被其他线程回收之前, 它的存储器资源(如栈)是不释放的。一个分离的线程是不能被其他线程回收或杀死的, 它的存储器资源在它终止时由系统自动释放
进程中的线程可以调用
pthread_join()
函数来等待某个线程的终止,获得该线程的终止状态,并收回所占的资源, 如果对线程的返回状态不感兴趣,可以将rval_ptr设置为NULL
int pthread_join(pthread_t tid, void **rval_ptr);
我们如果不关心线程终止状态,可以将线程设置为分离状态,也可以让线程以分离状态启动
int pthread_detach(pthread_t tid);//将线程设置为**分离状态**
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);//让**线程以分离状态启动**
2.2 线程的调度策略
POSIX(Portable Operating System Interface)标准指定了三种调度策略:
- 分时调度策略,SCHED_OTHER。这是线程属性的默认值,另外两种调度方式只能用于以超级用户权限运行的进程, 因为它们都具备实时调度的功能,但在行为上略有区别。
- 实时调度策略,先进先出方式调度(SCHED_FIFO)。基于队列的调度程序,对于每个优先级都会使用不同的队列, 先进入队列的线程能优先得到运行,线程会一直占用CPU,直到有更高优先级任务到达或自己主动放弃CPU使用权。
- 实时调度策略 ,时间片轮转方式调度(SCHED_RR)。与 FIFO相似,不同的是前者的每个线程都有一个执行时间配额, 当采用SHCED_RR策略的线程的时间片用完,系统将重新分配时间片, 并将该线程置于就绪队列尾,并且切换线程,放在队列尾保证了所有具有相同优先级的RR线程的调度公平。
2.3 线程的优先级
在Linux系统中,优先级数值越小, 线程优先级越高。仅当调度策略为实时(即SCHED_RR或SCHED_FIFO)时才有效, 并可以在运行时通过pthread_setschedparam()
函数来改变,默认为0。
2.3 线程实验
实验中创建一个进程,线程的属性是默认属性,在线程执行完毕后就退出
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>/*要执行的线程*/
void *test_thread(void *arg)
{int num = (unsigned long long)arg; /** sizeof(void*) == 8 and sizeof(int) == 4 (64 bits) */printf("This is test thread, arg is %d\n", num);sleep(5);/*退出线程*/pthread_exit(NULL);
}int main(void)
{pthread_t thread;void *thread_return;int arg = 520;int res;printf("start create thread\n");/*创建线程,线程为test_thread函数*/res = pthread_create(&thread, NULL, test_thread, (void*)(unsigned long long)(arg));if(res != 0){printf("create thread fail\n");exit(res);}printf("create treads success\n");printf("waiting for threads to finish...\n");/*等待线程终止*/res = pthread_join(thread, &thread_return);if(res != 0){printf("thread exit fail\n");exit(res);}printf("thread exit ok\n");return 0;
}
运行结果
以下是一些线程相关函数,创建一个线程
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
初始化线程对象的属性
int pthread_attr_init(pthread_attr_t *attr);
销毁一个线程属性对象
int pthread_attr_destroy(pthread_attr_t *attr);
设置、获取线程栈大小可以使用以下函数:
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize);
参数说明:
线程退出
void pthread_exit(void *retval);