原创内容,如有引用请注明出处
文章的篇幅较长,读者可以根据需要在目录索引下跳转需要阅读的部分。欢迎在评论区留言一起探讨问题。具体内容,请看目录
目录
一、 熟悉VM workstation Pro,安装Linux OS(Centos)
在Windows系统上运行Linux系统,首先要安装VM workstation,这个的下载在百度上一搜就有了,照做很简单的,在其上虚拟出Linux操作系统,这里我们安装的是Centos7。镜像文件是在阿里云的镜像网站下载的,这里附上网址:虚拟机镜像网站
下载后缀名是.iso的文件
放在之后你要安装的文件路径中,按照后面的blog安装即可linux系统安装
这里笔者也提供一个更基于gui的安装方法,更适合于初学者:
打开VM workstion Pro 的主页,点击创建新的虚拟机
选择典型配置,对于大部分新手用户,选择经典的配置模式就已经够了
选中之前在镜像网站上下载好的镜像文件的所在文件夹
命名并设置位置,位置个人建议就安装在c盘即可
直接下一步
点击完成,进入安装,接下来是linux操作系统的安装配置
一直等待,知道进入图形用户界面,并选择你要的语言,这里是中文,然后继续
进入这个界面后,每个用户根据需要,对每个选项进行需要的设置即可,这里特别强调一个选择–软件选择:
不使用最小安装,在里面根据需要选择一定程度的安装,我选择了基本安装带有开发工具的安装。在设置完成之后,点击开始安装等待系统完成安装即可。
在使用这之后,系统会自动给你安装VMware tools,这省去了很大的功夫,提供了很大的边界,使得可以在linux虚拟机和Windows操作系统形成“无缝”切换。如果读者没有安装tools,也可以根据这篇文章进行安装VMware tools
二、 熟悉Linux OS的基本使用,安装gcc编译器
接下来附上时长少且快速入门的在B站上的教程linux基本操作,这里笔者对其内容进行了笔记总结如下,欢迎使用:
hostname:显示当前目录
bc:Linux的计算器
quit:退出或ctrl c
ls:查看当前目录下有哪些文件 或 ls+目录
ls -l:显示详细信息
ls -a:显示隐藏文件
ls -d:查看目录
ls -h:增强可读性
ls -ld:查看目录自身,而不是目录下的文件
pwd:打印当前工作目录
cd:切换目录,语法 cd 目录名
cd -:回到上一个目录
cd .:回到当前目录
cd …:返回上一级目录
cat:查看文件内容
tac:倒序查看文件内容
more:查看问件内容,语法 more(不可上写翻页,只能一直往下,空格和回车刷屏和行)
less:查看文件内容 less 文件名(可上下翻页,q退出)
head:查看文件的前n行 ,less 文件名(可上下翻页),q退出
tail:查看文件后几行 语法 head 文件名
cp:复制文件 语法 cp 源文件 目标文件
mv:剪切文件 语法,mv 源文件 目标文件
touch:常用来创建空文件夹 语法,touch 文件名
mkdir:创建目录 语法,mkdir 目录名
vim编辑器
ctrl F:向下翻动一整页内容
ctrl B:向上翻动一整页内容
^:跳转至行首
: 跳 转 至 行 尾 G : 跳 转 至 文 件 的 末 尾 行 n G : 跳 转 到 文 件 中 的 第 n 行 g g : 跳 转 到 文 件 的 首 行 : s e t n u : 显 示 行 号 : s e t n o n u : 不 显 示 行 号 d d : 删 除 光 标 所 在 行 d : 删 除 光 标 之 前 到 行 首 的 所 有 字 符 d :跳转至行尾 G:跳转至文件的末尾行 nG:跳转到文件中的第n行 gg:跳转到文件的首行 :set nu:显示行号 :set nonu:不显示行号 dd:删除光标所在行 d^:删除光标之前到行首的所有字符 d :跳转至行尾G:跳转至文件的末尾行nG:跳转到文件中的第n行gg:跳转到文件的首行:setnu:显示行号:setnonu:不显示行号dd:删除光标所在行d:删除光标之前到行首的所有字符d:删除当前光标处到行尾的所有字符
dw:删除当前光标处到词尾的所有字符
yy:复制当前行整行的内容到剪贴板
P:将缓冲区中的内容粘贴到光标位置之后的位置
P:粘贴到光标位置处之前
/word:从上而下在文件中查找字符串“word”
?word:从下而上在文件中查找字符串“word”
u:按一次取消最近的一次操作,多次重复按u键,恢复已执行的多次操作
ZZ:保存当前的文件内容并退出vi编辑器
:w:保存文件
:q:未修改退出
:q!:放弃对文件内容的修改,并退出vi
:wq:保存文件并退出vi
: s /old/new:将当前行中查找到的第一个字符“old”串替换成“new”
: s /old/new:将当前行中查找的所有字符串old“替换为“new”
:%s /old/new/g:在整个文件范围内替换所有的字符串“old”为“new”
i:进行编辑
esc:退出文件编辑状态
rm:删除文件或目录 语法,rm [选项] 文件名/目录名(默认删除文件,不删除目录)
rm -r 目录名 (删除命令,并一个一个询问)
rm -rf 目录名 (不再询问,直接删除)
当然这里是部分内容,不过对于入门使用已绰绰有余。
三、 编写简单程序(C/Java/python),用gcc编译运行
对于简单程序的编写,当然是hello world了。依次执行下列操作即可:
vim hello.c
进入vi编辑器按i后输入程序
#include<stdio.h>
int main(){
printf("hello world\n");
return 0;
}
然后再输入下列命令
Esc + :wq
gcc hello.c
./a.out
得到的结果如图
四、编写生产者/消费者,编译执行,熟悉进程同步机制
对于生产者消费者问题,读者可以看这篇文章:生产者/消费者问题
下面是操作过程
vim consumer.c
i
// 输入我们要的程序,然后
esc + :wq
gcc consumer.c -o consumer
./consumer
下面是运行之后的截图
下面是具体的代码,在gcc下编译通过
#include <stdio.h>
#include <semaphore.h>
#include <stdlib.h>
#include <pthread.h>
sem_t sem_mutex, sem_full, sem_empty;
int buf_size;
int in = 0;
int out = 0;
int sleepTime();
void *producer(void *argu);
void *consumer(void *argu);
int main(int argc, char **argv)
{
int pro = 0;
int con = 0;
int total_pro, total_con;
again: printf("Please input the quantity of producer:\n");
scanf("%d", &total_pro);
printf("Please input the quantity of consumer:\n");
scanf("%d", &total_con);
printf("Please input the size of buffer:\n");
scanf("%d", &buf_size);
if(total_pro<=0 || total_con<=0 || buf_size<=0)
{
printf("\nInvalid argument: All above of the data must be a positive integer!\n");
printf("Please input the data again\n\n");
goto again;
}
pthread_t *thread_pro = (pthread_t*)malloc(sizeof(pthread_t)*total_pro);
pthread_t *thread_con = (pthread_t*)malloc(sizeof(pthread_t)*total_con);
sem_init(&sem_mutex, 0, 1);
sem_init(&sem_full, 0, 0);
sem_init(&sem_empty, 0, buf_size);
while(pro!=total_pro && con!=total_con)
{
pthread_create(&thread_pro[pro], NULL, producer, NULL);
pthread_create(&thread_con[con], NULL, consumer, NULL);
pro++;
con++;
}
printf("\n**********Accomplish to create all thread!***********\n\n");
while(1);
return 0;
}
int sleepTime()
{
int sleep_time;
while(1)
{
time_t period = time(NULL);
srand(period);
sleep_time = rand()%10;
if(sleep_time > 0 && sleep_time < 3)
{
return sleep_time;
}
}
}
void *producer(void *argu)
{
while(1){
sem_wait(&sem_empty);
sem_wait(&sem_mutex);
printf("###Producer put a thing into buffer[%d] sizeof(buffer)==%d \n", in, buf_size);
in = (in+1)%(buf_size);
sem_post(&sem_mutex);
sem_post(&sem_full);
sleep(sleepTime());
}
}
void *consumer(void *argu)
{
while(1){
sem_wait(&sem_full);
sem_wait(&sem_mutex);
printf("$$$Consumer got a thing from buffer[%d] sizeof(buffer)==%d \n", out, buf_size);
out = (out+1)%(buf_size);
sem_post(&sem_mutex);
sem_post(&sem_empty);
sleep(sleepTime());
}
}
五、编写银行家算法
银行家算法网上一堆介绍,笔者这里就不再赘述了,附上连接供读者学习银行家算法
下面是笔者自己写的银行家算法代码,在Linux操作系统下的gcc编译通过,供大家一起交流讨论
银行家算法我是先在vc++2010里面打好,然后用VMtools复制粘贴过去的,我将它保存在banker2.c的文件里,所以遇到了一些问题,比如采用语法for(int m;m<10;m++)、bool 定义布尔型变量等错误等待,它们在gcc下面编译。下面是解决办法,把int m 申明在for的外面即可,然后使用#include<stdbool.h>这个头文件就可以使用bool类型的变量了。这是解决bool申明的博客链接:解决bool无法编译问题
在终端使用linux命令
ctrl l
ls
gcc banker2.c -o banker
./banker
下面是代码运行的结果图
#include<stdio.h>
#include<stdbool.h>
int main()
{
int available[3]={
3,3,2};
int available2[3]={
3,3,2};
int max[5][3]={
{
7,5,3},{
3,2,2},{
9,0,2},{
2,2,2},{
4,3,3}};
int allocation[5][3]={
{
0,1,0},{
2,0,0},{
3,0,2},{
2,1,1},{
0,0,2}};
int allocation2[5][3]={
{
0,1,0},{
2,0,0},{
3,0,2},{
2,1,1},{
0,0,2}};
int need[5][3]={
{
7,4,3},{
1,2,2},{
6,0,0},{
0,1,1},{
4,3,1}};
int need2[5][3]={
{
7,4,3},{
1,2,2},{
6,0,0},{
0,1,1},{
4,3,1}};
bool flag;
bool safety(int work3[],int need3[5][3],int allocaion3[5][3]);
int number;
int temp[3] = {
0,0,0};
printf("you can use ctrl c to exit,if needed.\n");
printf("firtsly,examine the initial algrithm\n");
flag = safety(available2,need2,allocation2);
if(flag == true){
printf("\n初始算法是安全的\n");
}else{
printf("\n初始算法是不安全的");
}
int m;
for(m=0;m < 3;m++){
available2[m] = available[m];
}
int n;
for( m=0;m < 5;m++){
for( n=0; n <3;n++){
allocation2[m][n] = allocation[m][n];
need2[m][n] = need[m][n];
}
}
int i,j,k;
do{
bool signal;
do{
signal = true;
printf("输入需要分配资源的进程号:");
scanf("%d",&number);
printf("输入要分配的资源数:\n");
for( i=0;i < 3;i++){
printf("temp[%d]:",i);
scanf("%d",&temp[i]);
if(temp[i] <= need[number][i]){
if(temp[i] <= available[i]){
}else{
printf("资源尚不充足,需要等待!\n");
signal = false;
}
}else{
signal = false;
}
}
if(signal == false){
printf("输入不符合条件,请重新输入!\n");
}else{
for( k=0;k < 3;k++){
available2[k] = available2[k]-temp[k];
allocation2[number][k] = allocation2[number][k] + temp[k];
need2[number][k] = need2[number][k] - temp[k];
}
}
}while(!signal);
flag = safety(available2,need2,allocation2);
for( m=0;m < 3;m++){
available2[m] = available[m];
}
for( m=0;m < 5;m++){
for( n=0; n <3;n++){
allocation2[m][n] = allocation[m][n];
need2[m][n] = need[m][n];
}
}
if(flag == true){
printf("\n算法是安全的\n");
}else{
printf("\n算法是不安全的\n");
}
}while(true);
return 0;
}
bool safety(int work3[],int need3[5][3],int allocation3[5][3]){
int finish[5]={
0,0,0,0,0};
bool flag = true;
bool flag2 = true;
bool flag3 = false;
int sum = 0;
bool tip = false;
int i,j,p;
while(flag){
sum = 0;
flag3 = false;
for( i=0;i < 5;i++){
if(finish[i]==0){
flag2 = true;
for(j=0;j < 3;j++){
if(need3[i][j] <= work3[j]){
}else{
flag2 = false;
}
}
if(flag2 == true){
for(p=0;p < 3;p++){
work3[p] = work3[p] + allocation3[i][p];
}
finish[i] = 1;
printf("%d\t",i);
flag3 = true;
}else{
continue;
}
}else{
continue;
}
}
for( i=0;i < 5;i++){
sum += finish[i];
}
if(sum == 5){
tip = true;
break;
}else{
sum = 0;
}
if(flag3 == true){
flag = true;
}else{
flag = false;
tip = false;
}
}
return tip;
}