【操作系统作业-lab4】 linux 多线程编程和调度器

linux多线程编程

参考:https://blog.csdn.net/weibo1230123/article/details/81410241

https://blog.csdn.net/skyroben/article/details/72793409

 

1.背景知识

 Linux没有真正意义上的线程,它的实现是由进程来模拟,所以属于用户级线程,位于libpthread共享库(所以线程的ID只在库中有效),遵循POSIX标准。

 Linux上两个最有名的线程库LinuxThreads和NPTL。两个线程模型的比较:https://www.ibm.com/developerworks/cn/linux/l-threading.html

2.线程控制

在linux系统下,线程相关的函数都定义在pthread.h头文件中

创建线程函数-------pthread_creat函数

#include<pthread.h>
int pthread_creat(pthread_t thread, const pthread_attr_t* attr, void*(*start_routin)(void *), void* arg);

参数解释
* thread参数是新线程的标志符,为一个整型。
* attr参数用于设置新线程的属性。给传递NULL表示设置为默认线程属性。
* start_routin和arg参数分别指定新线程将运行的函数和参数。start_routin返回时,这个线程就退出了
* 返回值:成功为0,失败返回错误号

线程id的类型是pthread_t,它只在当前进程中保证是唯一的,在不同的系统中pthread_t可能有不同的实现,调用pthread_self()可以获取当前进程的id。

进程id的类型时pid_t,每个进程的id在整个系统中是唯一的,调用getpid()可以获得当前进程的id,是一个正整数值。

 

终止线程-------pthread_exit() 函数和 pthread_cancel()函数

终止某个线程而不是终止一个进程,可以可以有三种方法:

1.从线程函数return,在creat时候的第三个参数。这种方法对主线程不适应,从main函数return相当于调用exit。

2.一个线程可以调用Pthread_cancle终止同一进程中的另一个线程。

3.线程可以调用pthread_exit终止自己

#include<pthread.h>
int pthread_cancle(pthread_t thread);

*thread 是线程标识符
*该函数成功返回0,失败返回错误码

#include<pthread.h>
void pthread_exit(void *reval);

*retral 是void*类型,其他线程可以调用Pthread_join获得这个指针。需要注意,需要注意,pthread_exit或者return返回的指针所指向的内存单元必须是全局的或者是由malloc分 配的,不能在线程函数的栈上分配,因为当其它线程得到这个返回指针时线程函数已经退出了。
*pthread_exit函数通过retval参数向线程的回收者传递其退出的消息。它执行之后不会返回到调用者,且永远不会失败。

 

线程等待-----pthread_join

#include<pthread.h>
void pthread_join(pthread_t thread, void ** retval)

*调用该函数的线程将挂起等待,知道id为thread的线程终止
*thread线程以不同的方法终止,通过pthread_join得到的终止状态是不同的

 

3.分离线程

1.在任何一个时间点上,线程是可结合的(joinable)或者是分离的(detached)。

 2.一个可结合的线程能够被其他线程收回其资源和杀死。在被其他线程回收之前,它的存储器资源
(例如栈)是不释放的。(默认情况下线程的创建都是可结合的)

 3.一个分离的线程是不能被其他线程回收或杀死的,它的存储器 资源在它终止时由系统自动释放。

 4. 如果一个可结合线程结束运行但没有被join,会导致部分资源没有被回收,所以创建线程者应该调用pthread_join来等待线程运行结束,并可得到线程的退出代码,回收其资源。 

    linux线程执行和windows不同,pthread有两种状态joinable状态和unjoinable状态,如果线程是joinable状态,当线程函数自己返回退出时或pthread_exit时都不会释放线程所占用堆栈和线程描述符(总计8K多)。只有当你调用了pthread_join之后这些资源才会被释放。若是unjoinable状态的线程,这些资源在线程函数退出时或pthread_exit时自动会被释放。

    unjoinable属性可以在pthread_create时指定,或在线程创建后在线程中pthread_detach自己, 如:pthread_detach(pthread_self()),将状态改为unjoinable状态,确保资源的释放。或者将线程置为 joinable,然后适时调用pthread_join.
    其实简单的说就是在线程函数头加上 pthread_detach(pthread_self())的话,线程状态改变,在函数尾部直接 pthread_exit线程就会自动退出.

实例:

 1 #include <pthread.h>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #define NUM_THREADS    5
 5 
 6 struct msg{
 7   int id;
 8   char* word; 
 9 };
10 
11 //thread要运行的方法
12 void PrintHello(struct msg* arg)
13 {
14   printf("%s%d!\n", arg->word, arg->id);
15   arg->id=1000;
16   pthread_exit(NULL);
17 }
18 
19 int main(int argc, char *argv[])
20 {
21   pthread_t threads[NUM_THREADS];
22   //创建线程id
23   struct msg arg[NUM_THREADS];
24   //创建msg数组群
25   char* word = "Hello World! It's me, thread #";
26 
27   //分别创建5个线程
28   for(int t=0;t<NUM_THREADS;t++){
29     printf("In main: creating hread %d\n", t)t;
30     arg[t] = (struct msg){t, word};
31     pthread_create(&threads[t], NULL, &PrintHello, &arg[t]);  
32     //arg作为参数传入新线程运行的函数PrintHello里,四个参数分别是线程id,默认格式,线程运行的函数,函数参数。函数结束及新线程结束运行
33   }
34 
35   //让主线程依次等待各个线程执行完各自的函数后结束主线程
36   for(int t=0;t<NUM_THREADS;t++)
37     pthread_join(threads[t], NULL);//主线程挂起等待直到调用的函数结束
38   printf("\nall threads finish.\n");
39   /* Last thing that main() should do */
40   pthread_exit(NULL);//主线程终止自己
41 }

 

 

OS 调度器

1.几个概念

Program: a group of instructions to carry out a specified task 

      --stored on disk in some file

Process: an execution of certain program with its own address space and control of one or more threads

                 --resources: CPU, memory address, disk, IO ...

     --one program can invoke multipleprocesses

Thread: the unit of execution in CPU

Job: a series of program submitted to operating system for some goals

 

2.背景信息

OS 有三种进程调度队列:Job Queue,Ready Queue,DeviceQueue

Job Queue:进程都被存储在外部存储里,还未被唤醒的进程们。

Ready Queue:process 已经准备好 并且等待CPU来运行它们 , 存储在main memory里面

Device Queue:一个IO waitting queue,等待IO所以暂时让出CPU,blocked processes stored

 

multiprogramming 的degree:  the number of processes in memory

IO-bound process :  spends more time doing I/O than doing computations

CPU-bound process:doing I/O infrequently but using more time on computations

 

 3. 调度系统

一个作业(job)提交到操作系统后,将经历三种调度:

  -长期调度程序 long-term scheduler 

  -中期调度程序 medium-term scheduler

  -短期调度程序 short-term scheduler

 

-长期调度程序 long-term scheduler:

  选择disk里的进程,load 到ready queue里,选择时考虑IO-bound 和 CPU-bound

       调度器出现在job queue --->ready queue里面

-短期调度程序 short-term scheduler(也叫CPU scheduler)

   从ready queue里选择一个process,放到CPU里运行。

        调度器出现在ready queue到CPU的进度里,此处可以执行的调度算法有SJF,RR,priority等

-中期调度程序 medium-term scheduler(也叫swapping scheduler)

   swap一个process(或者是IO bound或者是CPU bound)出CPU,back into memory

      调度器出现在cpu--ready queue || job queue

 

三个调度系统的比较:

 

4.被CPU安排的进程的一生:

 

转载于:https://www.cnblogs.com/dallywang/p/10603437.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值