操作系统---“进程调度模拟程序” , “生产者―消费者问题算法的实现” , “银行家算法的实现”

2023-05-16

       如果有正在学习计算机操作系统的小伙伴,可以通过此文章对 进程调度模拟程序,生产者――消费者问题算法的实现,银行家算法的实现更加清楚。

      本人也只是一个学生,下面内容我主要整合了一些学习心得和成果,还有能够帮助自己快速掌握知识的视频,网站,链接。希望对你们有用。

1. 进程调度模拟程序

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;


struct PCB//类定义PCB表
{
    string ID;        //进程的名字
    int arrive_time; //进入进程队列的时间
    int CPUtime;     //进程运行完需要的时间
    int priority;  //优先级
    char status;//进程状态,"R"-运行态,"W"表示就绪态
};


vector<PCB> EnterReadyQueue;


//排序方式 按进入进程队列的时间先后排 时间相同则把运行时间长的放前面
bool cmp0(PCB a, PCB b) {
    if (a.arrive_time == b.arrive_time) {
        return a.CPUtime < b.CPUtime;
    }
    return a.arrive_time < b.arrive_time; //对时间进行排序。
}
//排序方式 按进入进程队列的优先级排 优先级相同则把进队时间先的放前面
bool cmp1(PCB a, PCB b) {
    if (a.priority == b.priority) {
        return a.arrive_time < b.arrive_time;
    }
    return a.priority > b.priority; //对时间进行排序。
}

void print_queue() { //打印当前就绪队列的情况。
    cout << "<-------------------------------->" << endl;
    cout << "进程名字     到达时间    需要运行的时间     优先数     进程状态" << endl;
    for (int i = 0; i < EnterReadyQueue.size(); i++) {
        cout << EnterReadyQueue[i].ID << "             "
            << EnterReadyQueue[i].arrive_time << "             "
            << EnterReadyQueue[i].CPUtime << "             "
            << EnterReadyQueue[i].priority << "             "
            << EnterReadyQueue[i].status << endl;
    }
    cout << "<-------------------------------->" << endl << endl;
}

void Rprint_queue() { //打印当前就绪队列的情况。
    cout << "<-------------------------------->" << endl;
    cout << "进程名字     到达时间    需要运行的时间     进程状态" << endl;
    for (int i = 0; i < EnterReadyQueue.size(); i++) {
        cout << EnterReadyQueue[i].ID << "             "
            << EnterReadyQueue[i].arrive_time << "             "
            << EnterReadyQueue[i].CPUtime << "             "
            << EnterReadyQueue[i].status << endl;
    }
    cout << "<-------------------------------->" << endl << endl;
}

void priority_way()//优先数算法的调用
{
    int w_time = 0;
    w_time = EnterReadyQueue[0].arrive_time + EnterReadyQueue[0].CPUtime;
    cout << "当前进程名字     进程到达时间    需要运行的时间     优先数" << endl;
    cout << EnterReadyQueue[0].ID << "               "
            << EnterReadyQueue[0].arrive_time << "               "
            << EnterReadyQueue[0].CPUtime << "               "
            << EnterReadyQueue[0].priority << endl;
            cout << EnterReadyQueue[0].ID << "在第" << w_time << "秒运行结束"<< endl<< endl;
            EnterReadyQueue.erase(EnterReadyQueue.begin());

    sort(EnterReadyQueue.begin(), EnterReadyQueue.end(), cmp1);   //重新排序
    print_queue();
    while(EnterReadyQueue.size() > 0)
    {

        PCB now = EnterReadyQueue.front();
       w_time  = w_time + now.CPUtime;
    cout << "当前进程名字     进程到达时间    需要运行的时间     优先数" << endl;
    cout << now.ID << "               "
            << now.arrive_time << "               "
            << now.CPUtime << "               "
            << now.priority << endl;
            cout << now.ID << "在第" << w_time << "秒运行结束"<< endl<< endl;
            EnterReadyQueue.erase(EnterReadyQueue.begin());
            if(EnterReadyQueue.size() != 0)
            print_queue();

    }
   cout << "<-------- 就绪队列为空,调度进程结束 ---------->" << endl << endl;
  cout << "进程总花费时间为 " << w_time << " 秒" << endl << endl;

}

void RR_way() // 时间片轮转算法的调用
{
    int q;  //时间片
    cout <<"<-------- 请输入时间片 ---------->" << endl;
    cin >> q;
    while(EnterReadyQueue.size() > 0)
    {
        PCB now = EnterReadyQueue.front();
        now.CPUtime  =  now.CPUtime - q;
        if(now.CPUtime <= 0)
            EnterReadyQueue.erase(EnterReadyQueue.begin());
            else
            {
                EnterReadyQueue.push_back(now);
                EnterReadyQueue.erase(EnterReadyQueue.begin());
            }
            if(EnterReadyQueue.size() != 0)
            Rprint_queue();
    }
    cout << "<-------- 就绪队列为空,调度进程结束 ---------->" << endl << endl;
}

void m_priority()//优先数算法
{
      int n;
    cout << "请输入要运行的进程数量: ";
    cin >> n;
    for (int i = 1; i <= n; i++) {
        PCB Pro;
        cout << "请输入第 " << i << " 个进程的名字: ";
        cin >> Pro.ID;
        cout << "请输入第 " << i << " 个进程的到达的时间: ";
        cin >> Pro.arrive_time;
        cout << "请输入第 " << i << " 个进程预计需要运行的时间: ";
        cin >> Pro.CPUtime;
        cout << "请输入第 " << i << " 个进程的优先级: ";
        cin >> Pro.priority;
        cout << endl;
        Pro.status = 'W';
        EnterReadyQueue.push_back(Pro); //加入进程就绪队列
    }
    sort(EnterReadyQueue.begin(), EnterReadyQueue.end(), cmp0); //对到来的时间排序

    print_queue();
    priority_way();
}
void m_RR()// 时间片轮转算法
{
     int n;
    cout << "请输入要运行的进程数量: ";
    cin >> n;
    for (int i = 1; i <= n; i++) {
        PCB Pro;
        cout << "请输入第 " << i << " 个进程的名字: ";
        cin >> Pro.ID;
        cout << "请输入第 " << i << " 个进程的到达的时间: ";
        cin >> Pro.arrive_time;
        cout << "请输入第 " << i << " 个进程预计需要运行的时间: ";
        cin >> Pro.CPUtime;
        cout << endl;
        Pro.status = 'W';
         Pro.priority = 0;
        EnterReadyQueue.push_back(Pro); //加入进程就绪队列
    }
    sort(EnterReadyQueue.begin(), EnterReadyQueue.end(), cmp0); //对到来的时间排序

    Rprint_queue();
    RR_way();

}

int main() {
    int x;
   cout << "<--------请选择使用哪一种算法 ---------->" << endl;
   cout << "1:优先级调度算法    2:时间片轮转调度算法 " <<endl;
   cin >> x;
   switch(x){
   case 1:m_priority();break;
   case 2:m_RR();break;
   }
   return 0;
}

(1)使用优先级调度算法

           

 优先级调度算法可以通过https://mbd.baidu.com/ma/s/asLPWulS此链接先进行学习,了解优先级调度算法的具体内容,再自己进行算法的实现。书本也有算法的介绍,但是我觉得上面链接讲的更简洁明了。

(2)时间片轮转调度算法

 时间片轮转算法相对简单,每次只要把第一个进程减去时间片,然后判断,如果减去之后小于0,那么说明该进程运行完毕,移除该进程,否则如果大于零说明载该时间片内未完成,那么将该进程移到末尾。课本上也讲的非常清楚。

 

 按照书上q = 4,的例子检验该代码可以得到下图:

 

 2.生产者――消费者问题算法的实现

老规矩 先上代码

#include<iostream>
#include<windows.h>
#include<thread>
#include<mutex>
#include<random>
#include<time.h>

using namespace std;

#define N 5


    int buffer[N];   //缓冲池
    int rear;        //指向缓冲池最末尾的产品
    mutex mu;        //互斥信号量
    int empty;       //空缓冲池区
    int full;        //满缓冲池区

    void init();           //初始化
    void insert(int item); //生产者生产产品
    void consumer1();      //消费者1
    void consumer2();       //消费者2
    void consumer2();       //消费者3
    //void remove(string name);
    void display();         //显示情况

void init()
{
    rear = -1;
    empty = N;
    full = 0;
}

void insert(int item)
{
    do {
        while (!empty)
        {
            //cout << "Producer is waiting for an empty slot..." << endl;
        }
          if(rear >= N-1)
        {
            cout <<"缓冲池已满" <<endl;
            break;
        }
        empty--;              //P(empty)
        mu.lock();            //P(mutex)
        cout << "生产的数为:" << item << endl;

        buffer[++rear] = item;  //产品放入缓冲区
        display();
        mu.unlock();            //V(mutex)
        full++;                //V(full)
        break;
    } while (1);
}


void display()
{
    cout << "缓冲区:";
    if (rear == -1)
        cout << "空" << endl;
    else {
        for (int i = 0; i <= rear; i++)
            cout << buffer[i] << " ";
        cout << endl;
    }
    cout << endl;
}

void producer()
{
    int item;
    srand((unsigned int)time(NULL));
    for (int i = 0; i < 20; i++)
    {
       item = rand() % 100 + 1;
       int e = rand() % 500;
        insert(item);
        Sleep(e);
    }
}

void consumer1()
{
    //for (int i = 0; i < 20; i++)
    while(1)
    {
        int e = rand() % 3000 ;
       // p->remove("消费者1号");
       int item;

    do {
        while (!full )
        {
           // cout << "Consumer is waiting for items..." << endl;
        }
        full--;

        mu.lock();
        if(rear != -1)
       item = buffer[rear--];    //从缓冲区取出产品
        cout << "消费者1号" << "消费的数为:" << item << endl;
        display();
        mu.unlock();            //V(mutex)
        empty++;             //V(empty)
        break;

    } while (1);
        Sleep(e);
    }
}

void consumer2()
{
    //for (int i = 0; i < 20; i++)
 while(1)
    {
        int e = rand() % 2000 ;
       // p->remove("消费者1号");
       int item;

    do {
        while (full <= 0)
        {
           // cout << "Consumer is waiting for items..." << endl;
        }
        full--;

        mu.lock();
        if(rear != -1)
       item = buffer[rear--];    //从缓冲区取出产品
        cout << "消费者2号" << "消费的数为:" << item << endl;
        display();
        mu.unlock();            //V(mutex)
        empty++;             //V(empty)
        break;

    } while (1);
        Sleep(e);
    }
}

void consumer3()
{
    //for (int i = 0; i < 20; i++)
 while(1)
    {
        int e = rand() % 2000 ;
       // p->remove("消费者1号");
       int item;

    do {
        while (full <= 0)
        {
           // cout << "Consumer is waiting for items..." << endl;
        }
        full--;

        mu.lock();
        if(rear != -1)
       item = buffer[rear--];    //从缓冲区取出产品
        cout << "消费者3号" << "消费的数为:" << item << endl;
        display();
        mu.unlock();            //V(mutex)
        empty++;             //V(empty)
        break;

    } while (1);
        Sleep(e);
    }
}

int main()
{
    init();
    thread pro(producer);    //创建生产者子线程
    thread con1(consumer1);    //创建消费者子线程
    thread con2(consumer2);    //创建消费者子线程
    thread con3(consumer3);
    pro.join();                  //阻塞主线程
    con1.join();
    con2.join();
    con3.join();
    cout << "结束!" << endl;
    return 0;
}

 

 

以上的例子可以先通过链接:https://mbd.baidu.com/ma/s/DhKQhJ7Q 进行学习,生产者消费者的问题其实很好理解,主要是代码实现不太容易。

上面链接主要写了如何创建线程,join和detach,传递参数,获取id和休眠,结束线程,并发访问,线程同步等,还有具体的例子。我觉得看完之后完全可以自己动手实现生产者――消费者问题算法。

下面是我补充的链接没有但是用的的知识。

(1)头文件的#include<mutex>

mutex互斥量是一个类,这个类有有一个lock()方法,和一个unlock()方法。 如果第一次运行了lock()这个方法,而没有运行unlock()这个方法,第二次再运行lock()这个方法时,程序就会卡停在这里,只有当运行了unlock()这个方法运行后,第二个lock()方法才会运行通过。就是运用这种“锁”的机制就可以保证两段代码独立运行。

(2) rand() % 100 + 1;

1到100的随机数,具体学习可以看https://www.bilibili.com/video/BV1et411b73Z?p=32。

我上面所写的和书上的有所不同,这里用到的是栈,每次从最后一位存取。而书上用的是循环队列,感兴趣的小伙伴可以自己试试修改一下。

3.银行家算法的实现

#include<iostream>

using namespace std;

#define P 5  //进程数
#define R 3  //资源种类
int maxs[P][R] = {{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};
int allocation[P][R] = {{0,1,0},{2,0,0},{3,0,2},{2,1,1},{0,0,2}}; //分配矩阵
int need[P][R] = {{7,4,3},{1,2,2},{6,0,0},{0,1,1},{4,3,1}};   //需求矩阵
int available[R] = {3,3,2}; //可用资源向量
int request[R];   //请求向量当前进程对各类资源的申请量,算法的入口参数
bool Finish[P];
int safeSeries[P]={0,0,0,0,0};//安全进程序列号
int num;

void showInfo()
{
	cout <<"\n------------------------------------------------------------------------------------\n" ;
	cout <<"当前系统各类资源剩余:";
    for(int j = 0; j < R; j++)
	{
        cout <<available[j] << " ";
    }
    cout <<"\n\n当前系统资源情况:\n";
    cout <<" PID\t Max\t\tAllocation\t Need\n";
    for(int i = 0; i < P; i++)
	{
       cout << "P" << i << "\t";
        for(int j = 0; j < R; j++)
		{
            cout <<maxs[i][j] << " ";
        }
        cout <<"\t\t";
        for(int j = 0; j < R; j++)
		{
           cout <<allocation[i][j] << " ";
        }
       cout <<"\t\t";
        for(int j = 0; j < R; j++)
		{
            cout <<need[i][j] << " ";
        }
        cout <<"\n";
    }
}

//打印安全检查信息
void SafeInfo(int *work, int i)
{
    int j;
    cout << "P" << i<< "\t";
    //打印工作向量work
    for(j = 0; j < R; j++)
        cout <<work[j]<<" ";
    cout <<"\t\t";

    //打印需求矩阵need
    for(j = 0; j < R; j++)
        cout <<need[i][j]<<" ";;
   cout <<"\t\t";

    //打印可分配矩阵allocation
    for(j = 0; j < R; j++)
       cout <<allocation[i][j]<<" ";;
	cout <<"\t\t";

    //打印work + allocation
    for(j = 0; j < R; j++)
        cout <<allocation[i][j]+work[j]<<" ";;
    cout <<"\n";
}


//判断一个进程的所需资源是否全为零
bool isAllZero(int kang)
{
	num = 0;
	for(int i = 0; i < R; i++ )
		if(need[kang][i] == 0)
			num ++;

	if(num == R)
		return true;
	else
		return false;
}

//安全检查
bool isSafe()
{
	bool flag = true;
	int safeIndex = 0;	//安全进程个数
	int allFinish = 0;	//可需资源为0的进程数
	//工作变量work:系统可提供给进程继续运行所需的各类资源数目
    int work[R] = {0};
	int r = 0;	//进程序号
	int temp = 0;	//辅助判断所有进程是否全部分配完成

	//预分配为了保护available
    for(int i = 0; i < R; i++)
        work[i] = available[i];

	//把未完成进程置为false
    for(int i = 0; i < P; i++)
	{
		bool result = isAllZero(i);
		if(result == true)
		{
			Finish[i] = true;
			allFinish++;
		}
		else
			Finish[i] = false;
    }
	//预分配开始
    while(allFinish != P)
	{
		num = 0;
		//检测进程所需资源是否符合剩余资源
        for(int i = 0; i < R; i++)
			if(need[r][i] <= work[i] && Finish[r] == false)
				num ++;

		//符合
		if(num == R)
		{
			if(flag)
			{
				flag = false;
				cout << "\n系统安全情况分析:\n";
				cout <<" PID\t Work\t\t Need\t \tAllocation\tWork+Allocation\n";
			}
			SafeInfo(work,r);
			//释放资源
			for(int i = 0; i < R; i++ )
				work[i] = work[i] + allocation[r][i];

			allFinish ++;
			safeSeries[safeIndex] = r;
			safeIndex ++;
			Finish[r] = true;
		}
		r ++;
		if(r >= P)
		{
			r = r % P;
			if(temp == allFinish)
				break;
			temp = allFinish;
		}
    }
	//判断系统是否安全
	for(int i = 0; i < P; i++)
	{
		if(Finish[i] == false)
		{
			cout <<"\n当前系统不安全!\n\n";
			return false;
		}
	}
	//打印安全序列
	cout <<"\n当前系统安全!\n\n安全序列为:";

	//打印安全序列
	for(int i = 0; i < allFinish; i++)
		cout <<safeSeries[i];
    return true;
}


int main()
{
    //输入的进程序号
    int curProcess = 0;
    //用于控制输入内容的准确性(非字符)
	int a = -1;
    showInfo();
	bool isStart = isSafe();
	//用户输入或者预设系统资源分配合理才能继续进行进程分配工作
    while(isStart)
	{
		//限制用户输入,以防用户输入大于进程数量的数字,以及输入其他字符(乱输是不允许的)
      	do
		{
			if(curProcess >= P || a < 0)
			{
				cout <<"\n请不要输入超出进程数量的值或者其他字符:\n";
				while(getchar() != '\n');//清空缓冲区
				a = -1;
			}
			cout <<"\n------------------------------------------------------------------------------------\n";
			cout <<"\n输入要分配的进程:";
			cin >> curProcess;
			a = curProcess;
			cout <<"\n";

		}while(curProcess >= P || a < 0);

		//限制用户输入,此处只接受数字,以防用户输入其他字符(乱输是不允许的)
		for(int i = 0; i < R; i++)
		{
			do
			{
				if(a < 0 )
				{
					cout << "\n请不要输入除数字以外的其他字符,请重新输入:\n";
					while(getchar() != '\n');//清空缓冲区
					a = -1;
				}
				cout <<"请输入要分配给进程 P" << curProcess << "的第 "<< i +1 << "类资源:";
				cin >> request[i];
				a = request[i];
			}while( a < 0);
		}

		//判断用户输入的分配是否合理,如果合理,开始进行预分配
		num  = 0;
        for(int i = 0; i < R; i++)
		{
            if(request[i] <= need[curProcess][i] && request[i] <= available[i])
				num ++;
            else
			{
				cout << "\n发生错误!可能原因如下:\n(1)您请求分配的资源可能大于该进程的某些资源的最大需要!\n(2)系统所剩的资源已经不足了!\n";
				break;
			}
        }

        //合理
        if(num == R)
		{
			num = 0;
            for(int j = 0; j < R; j++)
			{
				//分配资源
                available[j] = available[j] - request[j];
                allocation[curProcess][j] = allocation[curProcess][j] + request[j];
                need[curProcess][j] = need[curProcess][j] - request[j];
				//记录分配以后,是否该进程需要值为0了
				if(need[curProcess][j] == 0)
					num ++;
            }
			//如果分配以后出现该进程对所有资源的需求为0了,即刻释放该进程占用资源(视为完成)
			if(num == R)
			{
				//释放已完成资源
				for(int i = 0; i < R; i++ )
					available[i] = available[i] + allocation[curProcess][i];
				cout << "\n\n本次分配进程 P" << curProcess<< "完成,该进程占用资源全部释放完毕!\n";
			}
			else
				//资源分配可以不用一次性满足进程需求
				cout << "\n\n本次分配进程 P" << curProcess << "未完成!\n";

			showInfo();

			//预分配完成以后,判断该系统是否安全,若安全,则可继续进行分配,若不安全,将已经分配的资源换回来
            if(!isSafe())
			{
				for(int j = 0; j < R; j++)
				{
					available[j] = available[j] + request[j];
					allocation[curProcess][j] = allocation[curProcess][j] - request[j];
					need[curProcess][j] = need[curProcess][j] +request[j];
				}
				cout <<"资源不足,等待中...\n\n分配失败!\n";
            }
        }
    }

}

 

 

 银行家算法主要的原理也不是很难,书上也有给出银行家算法中的数据结构,银行家算法,安全性算法。认真阅读书本上的内容再结合代码就很容易理解。

最后,希望这篇文章能够对你们有帮助!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

操作系统---“进程调度模拟程序” , “生产者―消费者问题算法的实现” , “银行家算法的实现” 的相关文章

  • 可牛办公卸载的方法

    首先在桌面上右单击可牛办公的快捷方式 xff0c 找到可牛办公在电脑里面的目标位置 xff0c 然后在木匾位置所在的文件夹里搜索关键词officetemplate 然后打开这个文件夹 将这个应用程序删除 xff0c 如果你感觉对你有用 xf
  • HTML如何给页面设置滚动条 (简单,通俗易懂)

    当页面中给定一定大小的可视窗口时 xff0c 而内容的大小是比可视窗口大的时候 xff0c 这时候则需要 xff0c 是页面实现滚动效果 xff1a 此时需要在最外层的盒子上面加上 overflow scroll xff0c 并且给高度设置
  • SpringBoot自动配置原理和实践

    一 什么是SpringBoot的自动配置 SpringBoot自动配置 xff0c 英文是Auto Configuration xff1a 它是指基于你引入的依赖jar包 xff0c 对SpringBoot应用进行自动配置 它为Spring
  • 步骤五:PIXHAWK遥控器的使用

    采用福斯i6s遥控 1 连接飞控 打开遥控器 xff0c 接收机插上飞控 xff0c 再插上送的短接线 xff0c 进行匹配对码RX 2 遥控器长按两秒锁 xff0c system output mode Output mode按照图片这样
  • Linux常用命令:用户、权限管理

    目录 一 运行模式 二 用户管理 xff08 重点 xff09 1 添加用户 2 修改用户 3 设置密码 4 删除用户 5 查看当前用户 xff1a whoami 6 查看登录用户 xff1a who 7 查看登录用户 xff1a w 8
  • 二叉搜索树的第K大节点(leetcode每日打卡)

    目录 题解 代码 题解 本文解法基于此性质 xff1a 二叉搜索树的中序遍历为 递增序列 根据以上性质 xff0c 易得二叉搜索树的 中序遍历倒序 为 递减序列 因此 xff0c 求 二叉搜索树第 k 大的节点 可转化为求 此树的中序遍历倒
  • 【java】小票:设计一张奶茶店的小票

    一 小票如图所示 二 代码 xff08 1 xff09 Order类 package case1 import java util Calendar public class Order private static int count 6
  • Linux网络设置

    目录 一查看网络接口信息ifconfig 二 xff0c 查看看主机名称hostname 三 xff0c 查看路由条目route 四 xff0c 查看网络连接情况netstat 五 xff0c 获取socket统计信息ss 六 xff0c
  • 【python】本地音乐播放器(PyQt5界面版)

    大家好 xff0c 近期又学习了新内容 xff0c 所以迫不及待想分享出来 关于python Gui编写的界面版的音乐播放器 xff0c 能实现本地音乐的播放 目录 前期准备 设计界面 功能需求 播放 暂停 播放模式 时长显示 主窗体 打包
  • 投资 GameFi 前需知道的事?

    April 2022 Simon Data Source Footprint Analytics 2022 年的 GameFi 延续了去年的火热 xff0c 截止到 4 月 Footprint Analytics 统计到的 GameFi 项
  • agt-get install过程中发现依赖Depends错误的解决办法

    ubuntu在sudo apt get install g 43 43 时报错 xff1a Reading package lists Done Building dependency tree Reading state informat
  • windows自带的压缩/解压缩(zip/unzip)功能-Powershell 的应用之一

    压缩文件经常碰到 xff0c 一般可以下载免费的unzip软件 xff0c 但是要么很多广告 xff0c 要么用一段时间就要购买 其实windows自动的Powershell 就可以做压缩和解压的 Powershell 是微软用于计算机管理
  • 服务器应用与安全—— OpenEuler欧拉

    OpenEuler源于华为EulerOS操作系统 xff0c 通过社区合作 xff0c 打造创新平台 xff0c 构建支持多处理架构 统一和开放的操作系统 xff0c 推动软硬件应用生态繁荣发展 最新版 xff1a OpenEuler 21
  • 什么是人工智能?(深度好文,带你初步了解当下最火的AI)一定要看完!

    1 基本概念 定义 机器学习是一门研究如何通过计算手段 xff0c 利用经验提升自身性能的学科 人工智能 机器学习与深度学习三者间的关系如图1 1所示 1 1 人工智能定义 努力将通常由人类完成的智力任务自动化 1 2 机器学习定义 是一种
  • Java中Cookie详解

    最近复习到了Cookie和Session xff0c 这里系统的讲解一下Cookie和Session 在学习这个之前 xff0c 我们需要了解 xff0c 会话的定义 会话是指某一个人打开浏览器 xff0c 访问多个页面 xff0c 然后关
  • 关于ffmpeg,av_read_frame函数返回值小于0的错误

    自己写了一段将视频切成图片的程序 xff0c 在机器上运行 xff0c 发现每次切到10 就结束了 xff0c 截取av read frame返回值 xff0c 发现返回值是AVERROR EOF就是 541478725 xff0c 因为之
  • 在配置log4j.properties中出现问题 ERROR Could not find value for key log4j.appender.Console

    为了测试所有文件是否写好 xff0c 写了一个测试类运行程序 xff0c 报了几行的错误 xff0c 但是还是成功的输出的了数据库的东西 这里是需要在logj4f的配置文件中加上一些东西 xff0c 代码如下 xff1a 解决报错log4j
  • springboot项目启动报错:找不到或无法加载主类【已解决】

    在配 置完一个完整的springboot项目后 xff0c 需要测试是否正确配置 xff0c 出现未加载或未找到加载类的情况 xff0c 可能有以下原因 xff1a 首先需要观察启动类在项目中的位置 xff0c 确保启动类与其他层的包在同一
  • 对于 nested exception is java.net.ConnectException问题【已解决】

    当在springcloud遇到这类问题时 xff0c 需要排查控制器中的路径是否写对 xff0c 由于我报错的项目是一个模拟客户端访问查询业务功能 xff0c 下面是我的源代码 xff08 报错 xff09 xff1a public sta
  • 如何搭建一个基本的Spring项目【Maven】

    相信很多朋友在刚学习Spring时 xff0c 都会存在这个疑问 xff0c 如何正确搭建一个Spring项目 xff0c 以及中间的许多报错无法解决 xff0c 大家可以跟着我一起试一下 xff0c 有问题的朋友评论区见 1 Spring

随机推荐

  • 使用注解开发时需要添加包扫描器【出现问题的可以点进来看看】

    很多第一次接触Spring注解开发的同学 xff0c 在使用注解后容易报错 xff0c 那就很可能是没有在配置文件中加入包扫描器 那么可以往下看 xff0c 以下面这个简单的例子来学习 下面是一个简单的实体类 xff0c 通过Compone
  • 如何使用Autowried,以及与Resource的区别

    在使用注解开发的过程中 xff0c 有个经常会见面的朋友 Autowried xff08 自动装配 xff09 xff0c 刚接触的朋友肯定不能理解自动装配这个词的含义 简单解释一下 xff0c 自动装配将通过已知的类型自动分配对象 xff
  • SpringMVC遇到的有关实体类的报错

    今天在复习SpringMVC数据传参的时候 xff0c 出现了一个非常小的问题 xff0c 主要是为了实验如何将一个对象作为参数传递 xff0c 我创建了两个类 xff0c 但是由于被传递的对象的那个类没有用public 修饰 xff0c
  • app:checkDebugDuplicateClasses错误

    此异常完整表述为 org gradle api tasks TaskExecutionException Execution failed for task 39 app checkDebugDuplicateClasses 39 这类问题
  • LAMP网站架构

    一 LAMP网站架构 1 1 基本定义 LAMP是指一组通常一起使用来运行动态网站或者服务器的自由软件名称首字母缩写 Linux xff0c 操作系统Apache xff0c 网页服务器 MariaDB或MySQL xff0c 数据库管理系
  • pancakeswap薄饼添加流动性后实现永久锁仓

    添加完流动性后 xff0c 永久锁仓就是放弃对资金池的控制 xff0c 就是放弃了对流动性的所有权 xff0c 没有办法撤池子了 现在锁仓分为2种 xff0c 一个是丢黑洞永久锁仓 xff0c 另外一种是短期锁仓 xff0c 锁在智能合约中
  • ubuntu14.04 root用户登录方法

    如果你是刚刚装完ubuntu14 04系统 xff0c 你进去后是以普通用户登录的 xff0c 很多操作并没有权限 xff0c 要想获得全部权限可以以root用户登录 1 先解除root锁定 xff0c 为root用户设置密码 打开终端输入
  • pycharm终端常用指令

    在调试ppddle的时候下载的coco数据集过大 xff0c 一时没有注意不急的如何终止 xff0c 所以转载一个记一下 Terminal快捷键 功能 Tab 自动补全 Ctrl 43 a 光标移动到开始位置 Ctrl 43 e 光标移动到
  • 解决Mac电脑因kotlin插件禁用导致的Android Studio无法打开问题

    解决这个办法需要将Android Studio目录下的disabled plugins txt文档中的org jetbrains kotlin删除即可 文件位置 Users mac Library Application Support G
  • 实现生产者消费者进程(Java)

    目录 前言 一 实验要求 二 步骤 1 主类 2 消费者 3 生产者 4 超市 前言 消费者问题是操作系统中典型的进程同步互斥问题 xff0c xff08 英语 xff1a Producer Consumer problem xff09 x
  • python | Pandas库数据预处理-缺失值篇:info()、isnull()、dropna()、fillna()函数

    相关文章 python Pandas库导入Excel数据 xff08 xlsx格式文件 xff09 函数 xff1a read excel python Pandas库导入csv格式文件函数 xff1a read excel 目录 数据源
  • vue3学习笔记 2023

    vue文件 34 组件 34 是一种封装的思想 把相关业务逻辑的 34 js css html 34 都封装到一起 当需要调用 34 组件 34 的时候 只需要在html中期望的位置插入对应的 34 标签 34 即可 比如封装了一个 34
  • STP详解

    STP STP全称为 生成树协议 xff08 Spanning Tree Protocol xff09 xff0c 是一种网络协议 xff0c 用于在交换机网络中防止网络回路产生 xff0c 保证网络的稳定和可靠性 它通过在网络中选择一条主
  • 【Linux】线程篇---线程安全&&生产者消费者模型

    目录 1 线程安全概念 2 互斥的实现 2 1互斥锁 2 2互斥锁原子性的保证 2 3互斥锁接口 2 3 1初始化互斥锁 2 3 2互斥锁加锁接口 2 3 3解锁接口 2 3 4 销毁互斥锁接口 2 4代码验证锁的接口 3 同步的实现 3
  • 收藏版|史上最全机器学习优化器Optimizer汇总

    转载于收藏版 xff5c 史上最全机器学习优化器Optimizer汇总 掘金 juejin cn 作者 xff1a 苏学算法 链接 xff1a https juejin cn post 7084409806492008456 来源 xff1
  • 三种图像内插法(最近邻内插法、双线性内插法、双三次内插法)的做法 & 代码实现

    参考博客 数字图像处理学习笔记 xff08 四 xff09 数字图像的内插 度量 表示与质量 闭关修炼 暂退的博客 CSDN博客 数字图像处理学习笔记 xff08 七 xff09 用Pycharm及MATLAB实现三种图像内插法 xff08
  • Java实现生产者消费者案例

    目录 一 生产者消费者模式概述 二 生产者消费者案例 三 代码 奶箱类 xff08 Box xff09 生产者类 xff08 Producer xff09 xff1a 消费者类 xff08 Customer xff09 xff1a 测试类
  • 深度学习 - TensorFlow Lite模型,云侧训练与安卓端侧推理

    TensorFlow Lite模型 xff0c 云侧训练与安卓端侧推理 引言一 云侧深度模型的训练代码1 加载数据集的格式分析1 1 从数据集加载的数据格式1 2 对加载的数据进行处理 2 深度模型搭建3 模型训练 评估 保存 转换4 模型
  • /system/core/init/readme.txt对init.rc的解释

    init rc由许多的Action和Service组成 每一个语句占据一行 xff0c 并且各个关键字被空格分开 c规范中的 xff08 如 n xff09 反斜杠将被忽略 backslash escapes 而被认为是一个空格 xff0c
  • 操作系统---“进程调度模拟程序” , “生产者―消费者问题算法的实现” , “银行家算法的实现”

    如果有正在学习计算机操作系统的小伙伴 xff0c 可以通过此文章对 进程调度模拟程序 生产者 消费者问题算法的实现 银行家算法的实现更加清楚 本人也只是一个学生 xff0c 下面内容我主要整合了一些学习心得和成果 xff0c 还有能够帮助自