C程序片段并发性测试以及前趋图的自动生成

VX2012平台。C++完成主程序,JAVA实现界面。

所谓程序并发性是指在计算机系统中同时存在有多个程序,宏观上看,这些程序是同时向前推进的.在单CPU环境下,这些并发执行的程序是交替在CPU上运行的。分析程序之间的的可并发性,并利用伯恩斯坦条件来判定各程序之间能否并发执行,同时通过词法语法分析自动生成程序之间的前趋图(DAG图),对我们分析程序很有好处。

//by hfut yzk
#include"stdafx.h"
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<fstream>
using namespace std;
/************************************************************结构体定义************************************************************/
#pragma region    结构体定义
struct  kind
{
    string na;																									   //单词
    int num;																									   //内码
    string type;																							    	//类型
    int l,r;																											 //行列数
};
struct var_que									                                                           //每个变量对应俩个程序读写情况队列
{
    vector<int>r,w;
};
#pragma endregion</span>

/* ***********************************************************变量定义************************************************************** */
#pragma region    变量定义

int line=1,row=1;																						//行列号
//char c;
const int num_pro=10;																				//程序数量
map<char,int>ma;																						//运算符表
vector<kind>res;																						 //视图表
int tree[10000][30];                                                                                //字典树
int numv=0;int w[10000];                                                                    //字典树变量值
int key=0;  int flag=0;	int flag1=0;												    //key统计关键字,flag统计标识符
char *pro[100];																					    //程序文件路径名
ifstream in;																							    //文件对象
map<string,int>getid ;																		     //标识符编号
var_que vq[100];																				  //变量 对每个程序的读写情况
void  test_for_berstein();			                                                         //berstein条件的判定
#pragma endregion</span>

/* ***********************************************************函数声明**************************************************************/
#pragma region 函数声明

void start(int id);																				//启动函数
void testit(int id,char c,string s);													//标识符是否左值测试1
void testitf(int id,string s);																//标识符是否左值测试2
void init();																							//初始化函数
void insert(string s);																			//字典树插入函数
void reads()	;																						//读入数据
bool test(int u);																					//是否保留字前缀
void f1(char &c,int id)	;																	// 关键字标识符分析器
void f2(char &c)			;																		  //数字分析器
void f3(char &c)			;																		 //分界符、运算符等其他分析器
bool test_other(char x)	;																 //测试是否运算符
void  test_for_same_w(string s,int id) ;                                         //防止同程序的变量多次记录
void get_graph()			;																		  //生成前趋图		

#pragma endregion</span>

/************************************************************函数实现区************************************************************/

#pragma region 函数实现
/************************************************************初始化函数************************************************************/
void  init()
{
    //res.clear();
    flag=0;
	return ;
}

/*******************************************************字典树数据插入函数***********************************************************/
void insert(string s)
{
    int u=0;
    for(int i=0;i<s.size();i++)
    {
        if(tree[u][s[i]-'a']==0)
           tree[u][s[i]-'a']=++numv;
        u=tree[u][s[i]-'a'];
    }
    w[u]=key++;
	return ;
}

/***********************************************************读入数据函数***************************************************************/
void reads()
{
   ma['[']=1;ma[']']=2;ma[',']=3;ma[';']=4;ma['(']=5;ma[')']=6;ma['{']=7;ma['}']=8;
   ma['+']=9;ma['-']=10;ma['*']=11;ma['/']=12;ma['%']=13;ma['&']=14;ma['|']=15;ma['.']=16;
   string s;
   ifstream  inkey("H:/course/OS/OS_program/key.txt");					   //保留字读入
   while(s!="end")
   {
       inkey>>s;
       insert(s);
   }
																															//程序的读入
    pro[1]="H:/course/OS/OS_program/program1.txt";
    pro[2]="H:/course/OS/OS_program/program2.txt";
    pro[3]="H:/course/OS/OS_program/program3.txt";
	pro[4]="H:/course/OS/OS_program/program4.txt";
	pro[5]="H:/course/OS/OS_program/program5.txt";
	pro[6]="H:/course/OS/OS_program/program6.txt";
	pro[7]="H:/course/OS/OS_program/program7.txt";
	pro[8]="H:/course/OS/OS_program/program8.txt";
	pro[9]="H:/course/OS/OS_program/program9.txt";
	pro[10]="H:/course/OS/OS_program/program10.txt";

    for(int i=1;i<=num_pro;i++)
     {
         init();
         in.open(pro[i]);
         start(i);
         in.close();
     }
	return;
}

/*******************************************************是否保留字前缀测试器********************************************************/
bool test(int u)
{
    for(int i=0;i<26;i++)
    {
        if(tree[u][i]!=0)
			return 1;
    }
    return 0;
}

/******************************************************关键字标识符分析器************************************************************/
void f1(char &c,int id)
{
    int mark=1;
    string s;
    s+=c;
    int u=0;
    if(tree[u][c-'a']!=0)                                      //是否关键字
       u=tree[u][c-'a'];
    else
		 mark=0;
    while(c=in.get())                                         //关键字测试
    {
        if(!(c>='a'&&c<='z'))
          if(c!='_')
            if(!(c>='0'&&c<='9'))
              break;
        if(mark==1)
        {
             if(tree[u][c-'a']!=0)
               u=tree[u][c-'a'];
              else
				  mark=0;
        }
        s+=c;
    }
    if(test(u))	                                            //出现保留字前缀情况为标识符
	{
		mark=0;
	}
    kind t;                                                 //录入
    t.na=s;
    t.l=line;
    t.r=row;
    if(mark==0)
    {
        t.num=++flag;
        if(getid.find(s)==getid.end())                                                 //防止重复
         {
            getid[s]=++flag1;
         }
         int dex=(vq[getid[s]].r.size())-1;										    //防止同程序的变量多次记录
        if(dex>=0&&vq[getid[s]].r[dex]==id)
           ;
        else
			vq[getid[s]].r.push_back(id);

        t.type="     标识符";
      testit(id,c,s);                                                                                 //左值测试1
	   testitf(id,s);																					//左值测试2
    }
    else
    {
        t.num=w[u];
        t.type="     关键字";
    }
    res.push_back(t);
    return ;
}

/***************************************************************数字分析器**********************************************************/
void f2(char &c)
{
    string s;
    s+=c;
    c=in.get();
    while(c>='0'&&c<='9')
    {
        s+=c;
        c=in.get();
    }
    int mark=1;
    while(c>='a'&&c<='z')
      {s+=c;mark=0;c=in.get();}
    kind t;
    t.na=s;
    t.l=line;
    t.r=row;
    if(mark==1)
    {
        //char *p;
    //strcpy_(p,s.c_str());
    t.num=0;//t.num=atoi(p);
    t.type="    数字";
    }
    else
    {
        t.type="    error";
        t.num=0;
    }
    res.push_back(t);
    return ;
}                                 

/**********************************************分界符、运算符等其他分析器********************************************************/
void f3(char &c)
{
    string s;
    kind t;
    t.l=line;t.r=row;
    if(ma.find(c)!=ma.end())
    {
        t.na+=c;
        if(ma[c]<=8)
			 t.type="     分界符";
        else
			 t.type="     运算符";
        t.num=ma[c];
        c=in.get();
    }
    else
    {
        t.type="   关系运算符";
        if(c=='>')
        {
             c=in.get();
             if(c=='=')
             {
                 t.na=">=";
                 t.num=1;
                 c=in.get();
             }
             else
             {
                t.na=">";
                t.num=2;
             }
        }
       else if(c=='<')
        {
              c=in.get();
              if(c=='=')
              {
                t.na="<=";
                 t.num=3;
                 c=in.get();
              }
              else if(c=='>')
              {
                  t.na="<>";
                  t.num=4;
                  c=in.get();
              }
              else
              {
                  t.na="<";
                  t.num=5;
              }
        }
        else if(c=='=')
        {
            t.na="=";
            t.num=6;
            c=in.get();
        }
    }
    res.push_back(t);
    return ;
}

/**********************************************测试是否运算符***********************************************************************/
bool test_other(char x)
{
    if(x=='+'||x=='-'||x=='*'||x=='/'||x=='%'||x=='&'||x=='^'||x=='|')
      return 1;
    else
	  return 0;
}

/*********************************************同程序的变量记录判断****************************************************************/
void  test_for_same_w(string s,int id)
{
	   int dex=(vq[getid[s]].w.size())-1;										    //防止同程序的变量多次记录
                  if(dex>=0&&vq[getid[s]].w[dex]==id)
                          ;
                   else
					    vq[getid[s]].w.push_back(id);
}

/*********************************************左值测试器1************************************************************************/
void testitf(int id,string s)                                                                                          //测试++a/--a
{
	int ss=in.tellg();																										//定位当前文件指针位置
	int go=s.size()+2;																									//到该变量前面一个位置
	   in.seekg(-go,ios::cur);
    for(;;go++)
    {
		char c=in.get();
        if(c==' ')
		{
			 in.seekg(-2,ios::cur);
			continue;
		}
        else if(c=='+')
        {
               	 in.seekg(-2,ios::cur);
				  c=in.get();
				  if(c=='+')
		     	{
				test_for_same_w(s, id);
				  }
        }
		else if(c=='-')
        {
               	 in.seekg(-2,ios::cur);
				  c=in.get();
				  if(c=='-')
		     	{
				  test_for_same_w(s, id);
				  }
        }
        break;
    }
    go=ss-in.tellg();
    in.seekg(go,ios::cur);
}

/*********************************************左值测试器2************************************************************************/
void testit(int id,char c,string s)
{
    int go=0;
    int ss=in.tellg();
    for(;;go++)
    {
        if(c==' ')																															//忽略空格
		{
			c=in.get();
			continue;
		}
        else if(c=='=')																													//排除==干扰
        {
            if(in.peek()!='=')
             	test_for_same_w(s, id);
        }
        else if(test_other(c))
        {
            if(in.peek()=='=')
            	test_for_same_w(s, id);
        }
         if(c=='+')
        {
          if(in.peek()=='+')
             	test_for_same_w(s, id);
        }
         else if(c=='-')
        {
          if(in.peek()=='-')
             	test_for_same_w(s, id);
        }
        break;
    }
    go=ss-in.tellg();
    in.seekg(go,ios::cur);
}

/****************************************************总控程序******************************************************************/
void start(int id)																														//启动
{
    char c;
    c=in.get();
     while(1)
    {
        if(c=='@')break;
	/*	cout<<in.tellg();
		cout<<"c:"<<c<<":c"<<endl;*/
		if(int(in.tellg())==-1)break;
        while(c==' '||c=='\t')
		{
			c=in.get();
			row++;
		}
           if(c=='\n')
          {
              line++;
              row=1;
              c=in.get();
              continue;
          }
        if(c>='a'&&c<='z')
           f1(c,id);
        else if(c>='0'&&c<='9')
           f2(c);
        else
           f3(c);
        row++;
        if(c=='\n')
          {
              line++;
              row=1;
              c=in.get();
          }
    }
	 return  ;
}

/********************************************************  生成前趋图***********************************************************/
void get_graph()
{
	ofstream out("H:/course/OS/OS_program/graph.txt");
	out<< num_pro<<endl;
	 for(int i=1;i<=flag1;i++)
    {
              for(int w=0;w<vq[i].w.size();w++)
			  {
                    for(int r=0;r<vq[i].r.size();r++)
					{
						if(vq[i].w[w]<vq[i].r[r])                                                                         //写后读
							  out<<vq[i].w[w]<<" "<<vq[i].r[r]<<" "<<"1"<<endl;
						else if (vq[i].w[w]>vq[i].r[r])																	//读后写
						     out<<vq[i].r[r]<<" "<<vq[i].w[w]<<" "<<"2"<<endl;
					}
					 for(int ww=w+1;ww<vq[i].w.size();ww++)											//写后写
					{
							  out<<vq[i].w[w]<<" "<<vq[i].w[ww]<<" "<<"3"<<endl;
					}
               }
	 }
	 out<<-1<<endl;
	 return ;
}							

/********************************************************  伯恩斯坦条件判定程序并发性***********************************************************/
void  test_for_berstein()
{
	cout<<"According to the conditions of Berstein , The following programs can not be executed concurrently:\n";
	 for(int i=1;i<=flag1;i++)
    {
              for(int w=0;w<vq[i].w.size();w++)
			  {
                    for(int r=0;r<vq[i].r.size();r++)
					{
						if(vq[i].w[w]<vq[i].r[r])                                                                         //写后读
							  cout<<"Program"<<vq[i].w[w]<<" "<<"Program"<<vq[i].r[r]<<" "<<"for the conflict of RAW.\n"<<endl;
						else if (vq[i].w[w]>vq[i].r[r])																	//读后写
						     cout<<"Program"<<vq[i].r[r]<<" "<<"Program"<<vq[i].w[w]<<" "<<"for the conflict of  WAR.\n"<<endl;
					}
					 for(int ww=w+1;ww<vq[i].w.size();ww++)											//写后写
					{
							 cout<<"Program"<<vq[i].w[w]<<" "<<"Program"<<vq[i].w[ww]<<" "<<"for the conflict of  WAW.\n"<<endl;
					}
               }
	 }
	 return ;
}							

#pragma endregion</span>

/**************************************************主函数***************************************************************************/

int _tmain()
{
    reads();

	 test_for_berstein();
	get_graph();
	//cout<<"graph get successfully!\n";
    ofstream out("H:/course/OS/OS_program/res.txt");
   // out<<"单词"<<'\t'<<'\t'<<"二元序列"<<'\t'<<'\t'<<"类型"<<'\t'<<'\t'<<"位置(行,列)"<<endl;
    for(int i=0;i<res.size();i++)
      {
                          /*  out<<res[i].na<<'\t'<<'\t'<<"("<<res[i].num<<","<<
							res[i].na<<")"<<'\t'<<'\t'<<res[i].type<<'\t'<<'\t'<<"("<<res[i].l<<","
							<<res[i].r<<")"<<endl;*/
		                   out<<res[i].na<<'\t'<<'\t'<<res[i].type<<endl;
      }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-05 17:30:57

C程序片段并发性测试以及前趋图的自动生成的相关文章

JMeter并发性测试

JMeter并发性测试 一.JMeter简介 Apache JMeter是Apache组织开发的基于Java的压力测试工具.用于对软件做压力测试,它最初被设计用于Web应用测试但后来扩展到其他测试领域. 它可以用于测试静态和动态资源例如静态文件.Java小服务程序.CGI脚本.Java 对象.数据库, FTP服务器, 等等.JMeter 可以用于对服务器.网络或对象模拟巨大的负载,来在不同压力类别下测试它们的强度和分析整体性能.另外,JMeter能够对应用程序做功能/回归测试,通过创建带有断言的

JVM 并发性: Java 和 Scala 并发性基础

处理器速度数十年来一直持续快速发展,并在世纪交替之际走到了终点.从那时起,处理器制造商更多地是通过增加核心来提高芯片性能,而不再通过增加时钟速率来提高芯片性能.多核系统现在成为了从手机到企业服务器等所有设备的标准,而这种趋势可能继续并有所加速.开发人员越来越需要在他们的应用程序代码中支持多个核心,这样才能满足性能需求. 在本系列文章中,您将了解一些针对 Java 和 Scala 语言的并发编程的新方法,包括 Java 如何将 Scala 和其他基于 JVM 的语言中已经探索出来的理念结合在一起.

JVM 并发性: 阻塞还是不阻塞?

在任何并发性应用程序中,异步事件处理都至关重要.事件来源可能是不同的计算任务.I/O 操作或与外部系统的交互.无论来源是什么,应用程序代码都必须跟踪事件,协调为响应事件而采取的操作.Java 应用程序可采用两种基本的异步事件处理方法:该应用程序有一个协调线程等待事件,然后采取操作,或者事件可在完成时直接执行某项操作(通常采取执行应用程序所提供的代码的方式).让线程等待事件的方法被称为阻塞 方法.让事件执行操作.线程无需显式等待事件的方法被称为非阻塞 方法. 旧的 java.util.concur

&lt;&lt;操作系统精髓与设计原理&gt;&gt;读书笔记(一) 并发性:互斥与同步(1)

<<操作系统精髓与设计原理>>读书笔记(一) 并发性:互斥与同步 并发问题是所有问题的基础,也是操作系统设计的基础.并发包括很多设计问题,其中有进程间通信,资源共享与竞争,多个进程活动的同步以及分配给进程的处理器时间的. 和并发相关的关键术语:原子操作: 一个或多个指令的序列,对外是不可分的:即没有其他进程可以看到其中间状态或者中断此操作. 并发中,为了确保并发下的数据完整性,我们有一系列的同步方法,其实这些就是为了实现互斥性!对临界区程序的互斥性.有三种方法: 1.软件方法,但是

浅谈并发性模型的测试策略

目前市面上的不少软件都会用到多方登录或者编辑的并发性问题,针对并发性问题有若干种方法,主要有以下几种: 保守方式:这种并发性模型在数据上加了锁.如果一个用户已经打开了一条记录,那么在允许编辑的环境中,系统就会拒绝来自其他用户的读取数据请求.适用于出现一个以上用户同时编辑相同数据的情况.(缺点:当一个用户已经打开某个数据时,其他用户就不能访问它了,这样导致了系统在使用上有些不方便.由于系统需要管理这些记录锁,所以模型在实现上也会有一定的复杂度.) 开放方式:总是允许用户读取数据,甚至还可能允许更新

SqlIte数据库并发性

把遇到的一些小问题都记下来,告诉自己,一些小细节会铸成打错的 今天没事复习以前的知识,用sqlite做数据库,发现修改数据的时候等好久才有反应,而且还失败,可是过一会之后又会好,好了以后又是一样,种以为是自己的语句有问题,测试了好多次,感觉没问题,在到网上查查错误才发现,原来sqlite不可以并发处理数据,我要说的不是这个问题,一个好的习惯可以避免所有的小问题,前面的解决方法就是把datareader等要释放的释放,关闭的关闭就可以,这本来就是要的,但是自己却没有这么做,这一个小问题纠结了我一个

探索 ConcurrentHashMap 高并发性的实现机制

简介 ConcurrentHashMap 是 util.concurrent 包的重要成员.本文将结合 Java 内存模型,分析 JDK 源代码,探索 ConcurrentHashMap 高并发的具体实现机制. 由于 ConcurrentHashMap 的源代码实现依赖于 Java 内存模型,所以阅读本文需要读者了解 Java 内存模型.同时,ConcurrentHashMap 的源代码会涉及到散列算法和链表数据结构,所以,读者需要对散列算法和基于链表的数据结构有所了解. Java 内存模型 由

深入了解 Scala 并发性

2003 年,Herb Sutter 在他的文章 “The Free Lunch Is Over” 中揭露了行业中最不可告人的一个小秘密,他明确论证了处理器在速度上的发展已经走到了尽头,并且将由全新的单芯片上的并行 “内核”(虚拟 CPU)所取代.这一发现对编程社区造成了不小的冲击,因为正确创建线程安全的代码,在理论而非实践中,始终会提高高性能开发人员的身价,而让各公司难以聘用他们.看上去,仅有少数人充分理解了 Java 的线程模型.并发 API 以及 “同步” 的含义,以便能够编写同时提供安全

6、Java并发性和多线程-并发性与并行性

以下内容转自http://tutorials.jenkov.com/java-concurrency/concurrency-vs-parallelism.html(使用谷歌翻译): 术语并发和并行性通常用于多线程程序.但是,并发和并行性究竟是什么意思呢,它们是相同的术语还是什么? 简短的答案是“不”.它们不是相同的术语,尽管它们在表面上看起来非常相似.也花了我一些时间来终于找到并了解并发和并行性之间的区别.因此,我决定在这个Java并发教程中添加一个关于并发性与并行性的文本. 并发 并发意味着