西电操作系统:进程程序复习
Proccess And Thread
1、fork()和exec()的区别
fork()
创建新的进程,父子进程拥有相同的内存映像;
对于父进程来说fork获得的pid是创建的子进程的pid,对于子进程来说fork获得的pid是0;
#include <unistd.h>
#include <stdio.h>
int main(){pid_t pid;pid = fork();if( pid == 0 ){while(1){sleep(1);printf("haha\n"); //子进程会一直打印haha}}if( pid > 0 ){while(1){sleep(1);printf("hehe\n"); //父进程会一直打印hehe}}return 0;
}
exec()
是以新的程序去代替原来的程序,但进程的PID保持不变。因此,可以这样认为,exec系统调用并没有创建新的进程,只是替换了原来进程上下文的内容。原进程的代码段,数据段,堆栈段被新的进程所代替。fork()
后产生父子进程,拥有相同内存印象。子进程执行exec,修改内存映像,运行新的程序.
#include <unistd.h>
#include <stdio.h>
int main(){pid_t pid;pid = fork();if(pid==0){execl("/bin/ls", "ls", "-l", 0); //子进程切换,调用执行新的程序,不再会打印出hahawhile(1){sleep(1);printf("haha\n");}}if(pid>0){while(1){sleep(1);printf("hehe\n"); //父进程继续打印hehe}}
}
2、pthread
#include <stdio.h>
#include <pthread.h>
int a;
void * th(void *p){int i = 0;while(1){a = 1; i++;sleep(1);if(i<5)printf("haha\n");}
}
int main()
{int i = 0;a = 0;pthread_t myth;pthread_create(&myth, NULL, th, NULL);while(1){i++; sleep(1);if(i <= 5)printf("a=%d hehe\n", a);}return 0;
}
pthread_create(&myth, NULL, th, NULL)
生成了线程:表示要执行的程序标段。
3、进程和线程的区别
同一个进程的线程之间是共享:程序段,数据段,代码段的
但是:PSW,PC,堆栈,寄存器是不共享的。
4、Mutual Exclusion with Busy waiting
(1) 锁变量
连续测试一个变量直到出现某个值为止,称为忙等待。
用于忙等待的锁称为自旋锁。
while(TRUE){while(turn!=0); /*忙等待*/critical_region();turn = 1;noncritical_region();
}while(TRUE){while(turn!=1);/*忙等待*/critical_region();trun = 0;noncritical_region(;)
}
需要严格地轮换执行
(2) Peterson解法
用了两个变量避免轮转:
#define FALSE 0
#define TRUE 1
#define N 2int turn;
int interested[N];void enter_region(int process)
{int other;other = 1 - process;interested[process] = TRUE;turn = process;while(turn == process && interested[other] == TRUE); //空语句,无法进入关键区
}void leave_region(int process){interested[process] = FALSE; //表示离开临界区
}
(3) TSL指令
TSL RX, LOCK
:测试并加锁;将锁字lock读到寄存器RX中,然后将锁值设为1;
读字和写操作保证是不可分的。即该指令结束前不允许其他处理器访问该内存字。执行TSL指令需要锁住总线
注意,在TSL指令中,LOCK为0是表示未上锁,为1时表示上锁
enter_region:TSL REGISTER, LOCK |复制锁值到寄存器,并将锁设置为1CMP REGISTER, #0 |锁是0吗?是0表示没有上锁,可以进入关键区JNE enter_region |锁值非零,已经上锁,不能进入关键区RET |返回调用者,进入临界区leave_region:MOVE LOCK, #0 |将锁值设置为0,解锁RET |离开关键区
另外TSL指令可以被XCHG指令代替:
enter_region:MOVE REGISTER, #1XCHG REGISTER, LOCKCMP REGISTER, #0JNE enter_regionRET
leave_region:MOVE LOCK, #0RET
5、Sleeping and Wakeup
具有严重的竞争条件的生产者与消费者问题。
丢失唤醒信号!!!会导致整个的睡眠
6、信号量
#define N 100
typedef int semaphore;
semaphore mutex = 1;
semaphore empty = N;
semaphore full = 0;void produce()
{int item;while(TRUE){item = produce_item();down(&empty);down(&mutex);isert_item(item);up(&mutex);up(&full); }
}void consume()
{int item;while(TRUE){down(&full);down(&mutex);item = remove_item();up(&mutex);up(&empty);consume_item(item);}
}
7、互斥量
信号量的简化版本。仅适用于管理共享资源或一小段代码。在实现用户空间线程包时非常有用。值只有0和1。这是不同于semaphore的显著区别。
mutex_lock:TSL REGISTER, LOCKCMP RESISTER, #0JZE ok |锁是0吗?是零的话,那么跳转CALL thread_yield |与忙等待不同之处,让出了CPU的使用权JMP mutex_lock
ok: RET
mutex_unlock:MOVE mutex, #0RET
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LX7C5J9V-1625280764315)(C:/Users/%E5%AD%99%E8%95%B4%E7%90%A6/AppData/Roaming/Typora/typora-user-images/image-20210621184404415.png)]
互斥量和conditional variable联合使用,解决生产者和消费者问题:
#include<stdio.h>
#include<pthread.h>
#define MAX 1000000000 /*需要生产的数量*/
pthread_mutex_t the_mutex;
pthread_cond_t condc, condp;
int buffer = 0;void *producer(void *ptr)
{int i;for(i = 1; i<= MAX;i++){pthread_mutex_lock(&the_mutex); //给mutex上锁while(buffer! = 0)pthread_cond_wait(&condp, &the_mutex);buffer = i;pthread_cond_signal(&condc); //唤醒消费者pthread_mutex_unlock(&the_mutex); //释放缓冲区}pthread_exit(0);
}void consumer(void *ptr)
{int i;for(i = 0; i<=MAX; i++){pthread_mutex_lock(&the_mutex);while(buffer == 0)pthread_cond_wait(&condc, &the_mutex);buffer = 0;pthread_cond_signal(&condp); //唤醒生产者pthread_mutex_unlock(&the_mutex);}pthread_exit(0);
}int main()
{pthread_t pro, con;pthread_mutex_init (&the_mutex, 0);pthread_cond_init(&condc, 0);pthread_cond_init(&condp, 0);pthread_create(&con, 0, consumer, 0);pthread_create(&pro, 0, producer, 0);pthread_join(pro, 0);pthread_join(con, 0);pthread_cond_destory(&condc);pthread_cond_destory(&condp);pthread_mutex_destory(&the_mutex);
}
8、经典IPC问题
(1)哲学家就餐问题
#define N 5
#define LEFT (i+N-1)%N
#define RIGHT (i+1)%N
#define THINKING 0
#define HUNGRY 1
#define EATING 2typedef int semaphore;
int state[N];
semaphore mutex = 1; //对状态表的互斥访问
semaphore s[N]; //到底有无获得叉子void philosopher(int i)
{while(TRUE){}
}void take_forks(int i)
{down(&mutex); //保护状态表state[i] = HUNGRY;test(i); //询问一下邻居能不能吃up(&mutex); down(&s[i]); //拿不到叉子会阻塞
}void put_forks(i)
{down(&mutex);state[i] = THINKING;test(LEFT);test(RIGHT);up(&mutex);
}void test(i)
{if(state[i] == HUNGERY && state[LEFT] != EATING && state[RIGHT] != EATING){state[i] = EATING;up(&s[i]);}
}
(2)读者写者问题
typedef int semaphore;
semaphore mutex = 1; //互斥:rc
semaphore db = 1; //互斥:数据库访问
int rc = 0; //读者数void reader()
{while(TRUE){down(&mutex);rc = rc+1;if(rc==1)down(&db);up(&mutex);read_data_base;down(&mutex);rc = rc -1;if(rc == 0) up(&db);up(&mutex);use_data_read;}
}void writer()
{while(TRUE){think_up_data();down(&db);write_data_base();up(&db);}
}
9、消息传递解决生产者和消费者问题
#define N 100
void producer(void)
{int item;message m;while(TRUE){item = produce_item();receive(consumer, &m);build_message(&m, item);send(consumer, &m);}
}void consumer(void)
{int item, i;message m;for(int i = 0;i<N;i++){send(producer, &m);}while(TRUE){}
}
#define N 100
void producer(void)
{int item;message m;while(TRUE){item = produce_item();receive(consumer, &m);build_message(&m, item);send(consumer, &m);}
}void consumer(void)
{int item, i;message m;for(int i = 0;i<N;i++){send(producer, &m);}while(TRUE){}
}
西电操作系统:进程程序复习相关推荐
- 西电 操作系统课设 在Ubuntu18.04安装pintos
西电 操作系统课设 在Ubuntu18.04安装pintos 前言 1. 主要步骤 2. VMware的安装 3. Ubuntu18.04的安装和配置 4. Bochs的安装 4. Pintos安装 ...
- 西电操作系统上机实验2
欢迎各位学弟学妹收藏操作系统上机详解,大家有空也可以看看这篇文章哦--西电计科课程学习 实验2:线程共享进程数据 一.实验目的 1.学习创建线程实现多工作同步运行; 2.了解线程与进程之间的数 ...
- 西电操作系统上机实验3
欢迎各位学弟学妹收藏操作系统上机详解,大家有空也可以看看这篇文章哦--西电计科课程学习 实验3:信号通信 一.实验目的 利用信号通信机制在父子进程及兄弟进程间进行通信. 二.实验内容 父进程创 ...
- 西电操作系统上机实验4
欢迎各位学弟学妹收藏操作系统上机详解,大家有空也可以看看这篇文章哦--西电计科课程学习 实验4:匿名管道通信 一.实验目的 学习使用匿名管道在两个进程间建立通信. 二.实验内容 父进程创建一个 ...
- 西电操作系统上机实验1
欢迎各位学弟学妹收藏操作系统上机详解,大家有空也可以看看这篇文章哦--西电计科课程学习. 实验1:创建进程 一.实验目的 学会通过基本的Windows进程控制函数,由父进程创建子进程. 二.实验内 ...
- 西电计算机通信与网络复习
<计算机通信与网络>课程总复习知识点 *配套<数据通信与网络(Forouzan第四版)>*2021年12月 第一部分 概述 第1章 绪论 1. 数据通信的概念及模型 数据通信 ...
- 西电操作系统上机实验6
实验6:共享主存实现进程通信 一.实验目的 进程同步是操作系统多进程/多线程并发执行的关键之一,进程同步是并发进程为了完成共同任务采用某个条件来协调他们的活动,这是进程之间发生的一种直接制约关系. ...
- 西电计网期末复习要点+iPad手写笔记
本人计网94,下面是我当时复习的时候整理的笔记,供各位学弟学妹参考.
- 西电研一人工智能复习随笔
记:人工智能和先进人工智能写在一起了,懒得分开写 目录 第一章 第二章 知识表示方法 知识表示 知识表示方法 状态空间法 问题归约法 谓词逻辑法(重点 但是不单独考察) 语义网络法 第三章:搜索技术 ...
- 西电计科操作系统实验
#西电计科操作系统实验: ##操作系统的实验方敏老师和黄伯虎老师要求并不一样,方敏老师的OS实验比起黄伯虎老师简直轻松的不值一提,因此选课的时候,建议大家选方敏老师,性价比更高! ##本次给大家介绍的 ...
最新文章
- 利用CxImage实现编解码Gif图像代码举例
- html和css之间有什么区别,html语法和css语法之间有什么区别
- centos 7 minimal connect: Network is unreachable和ifconfig command not found
- 数据库开发——MySQL——数据的增删改查
- Android开发之recyclerview布局加载不全的问题
- Powershell 查看软件是否成功安装
- 要做PPT,一直找不到资源?
- 【牛客 - 21302】被3整除的子序列(线性dp)
- Thinkphp系统常量
- python中ln怎么表示_Python math库 ln(x)运算的实现及原理
- 决策树留一法python代码_ScikitLearn决策树算法类库使用小结
- pyqt5-控件是否可用
- 股票市值高好还是低好呢?
- python中读取文本文件_利用Python读取文本文件?
- MySQL百万级高并发网站优化
- Entity Framework之IQueryable和list本地集合
- 写了一个很矬( cuó)的移动端用户管理
- linux 常用命令详解(文件处理命令,权限管理命令,文件搜索命令,帮助命令,用户管理命令,压缩解压命令,关机重启命令)
- UML图的画法,简单详细,以实战代码为例子画UML
- 【工具篇】OBS推流在Bilibli直播平台的设置和应用