createmutex

时间:2024-06-27 02:31:14编辑:奇闻君

如何防止程序重复运行

如何防止程序重复运行
一个vc的程序,由于使用了1394相机和串口资源,在多次运行时死机。
在App::InitInstance()中加入
CreateMutex(NULL,true,m_pszAppName);
if(GetLastError() == ERROR_ALREADY_EXISTS)
{
AfxMessageBox(_T("应用程序不可以重复启动"),MB_OK | MB_APPLMODAL | MB_ICONSTOP);
return(false);
}

把m_pszAppName换成程序的GUIDe值即可。一般在stdafx.h有,例如
#if !defined(AFX_STDAFX_H__A5EA48F2_0257_4B04_B771_A2E1635741D8__INCLUDED_)
#define AFX_STDAFX_H__A5EA48F2_0257_4B04_B771_A2E1635741D8__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
则GUID为:A5EA48F2_0257_4B04_B771_A2E1635741D8
这个值就是的程序ID,可定义为:
#define MY_GUID "{A5EA48F2_0257_4B04_B771_A2E1635741D8}"
然后把MY_GUID替换上面的m_pszAppName的即可。


如何理解createmutex

第一种方法,在程序没有执行 CreateMutex和OpenMutex 这两个api之前 Hook,一般都是主线程开始的代码,如果用一个程序检查该程序运行然后hook,根本就来不及Hook,因为Hook了的时候,该程序早就把这 2个函数执行了,除非要hook windows系统的程序装载器,当装载器把程序的代码映射到内存后,挂起该进程,然后hook第二种方法,修改该程序的exe文件,把里面的导入表中这2个api的dll文件名修改成你自己写的dll文件名,然后在自己写个dll,改程序调用你写的dll中的api,随便想返回给他什么值自己看着办。第三种方法,也是最好的方法,下载一个反汇编工具,找到 使用 这2个api的地方,肯定有个判断语句,判断是否多开,正常的是有多开,就结束程序,现在修改那个判断的汇编指令即可。


在VC中怎么实现一个程序不能被同时打开多次

::CreateMutex(NULL,TRUE,"MutexName");//字符串里面的内容可以随便改.他只是一个名字
if(GetLastError()==ERROR_ALREADY_EXISTS)
{
AfxMessageBox("你已经打开了该程序");
exit(0);
return;
}


把上面的代码加入到工程里面的构造函数里面。

原理是在windows内核创建一个Mutex(互斥),根据创建的返回值判断是否2重启动。不管ERROR_ALREADY_EXISTS

::CreateMutex(NULL,TRUE,"MutexName");//创建一个互斥,名字为"MutexName"
if(GetLastError()==ERROR_ALREADY_EXISTS)//判断刚才发生了什么错误。
//当第一次启动的时候,GetLastError()获得的错误是ERROR_SUCCESS所以程序继续运行。windows内核已经存在一个名为"MutexName"的互斥.直到你用ReleaseMutex("MutexName")语句释放掉他,或者当前进程结束。

//当第二重启动的时候,内核已经有一个名为"MutexName"的互斥,所以创建会失败,通过GetLastError()判断上次失败的原因是ERROR_ALREADY_EXISTS,证明已经有个进程存在,exit(0)是结束进程。


个人感觉上段代码放在构造函数里面比放在InitInstance函数内要好。


死锁解决C语言程序

#include
#include
#include
const unsigned short SIZE_OF_BUFFER = 1; //缓冲区长度
int g_buffer[SIZE_OF_BUFFER];
bool g_continue = true; //控制程序结束
HANDLE g_hMutex; //用于线程间的互斥
DWORD WINAPI FatherProc(LPVOID); //父进程线程
DWORD WINAPI SonProc(LPVOID); //使用打印机的线程
int main()
{
//创建各个互斥信号
g_hMutex = CreateMutex(NULL,FALSE,NULL);
const unsigned short FATHERS_COUNTS = 1; //父进程线程的个数
const unsigned short SONS_COUNT = 2; //使用打印机的线程的个数

//总的线程数
const unsigned short THREADS_COUNT = FATHERS_COUNTS+SONS_COUNT;
HANDLE hThreads[THREADS_COUNT]; //各线程的handle
DWORD fatherID[FATHERS_COUNTS]; //父进程线程的标识符
DWORD sonID[SONS_COUNT]; //使用打印机的线程的标识符

//父进程线程
for (int i=0;i<FATHERS_COUNTS;++i){
hThreads[i]=CreateThread(NULL,0,FatherProc,NULL,0,&fatherID[i]);
if (hThreads[i]==NULL) return -1;
}
//使用打印机的线程
for (i=0;i<SONS_COUNT;++i){
hThreads[SONS_COUNT+i]=CreateThread(NULL,0,SonProc,NULL,0,&sonID[i]);
if (hThreads[i]==NULL) return -1;
}
while(g_continue){
if(getchar())
{ //按回车后终止程序运行
g_continue = false;
}
}
return 0;
}
//分配打印机
void Append()
{
srand((unsigned)time(0));
std::cerr << "打印机空闲 ...\n";
if(rand()%2)
{
g_buffer[0]=1;//给PA
}
else
{
g_buffer[0]=0;//给PB
}
}
//son使用打印机
void Take()
{
if(g_buffer[0]==1)
{
std::cerr << "PA使用打印机 ... ";
std::cerr << "成功" << std::endl<<std::endl; ;
};
if(g_buffer[0]==0)
{
std::cerr << "PB使用打印机 ... ";
std::cerr << "成功" << std::endl<<std::endl; ;
};
g_buffer[0]=-1;
}
//父进程
DWORD WINAPI FatherProc(LPVOID lpPara)
{
while(g_continue){
WaitForSingleObject(g_hMutex,INFINITE);
Append();
Sleep(1500);
ReleaseMutex(g_hMutex);
}
return 0;
}
//子进程
DWORD WINAPI SonProc(LPVOID lpPara)
{
while(g_continue){
WaitForSingleObject(g_hMutex,INFINITE);
Take();
Sleep(1500);
ReleaseMutex(g_hMutex);
}
return 0;
} 最后的要求自己添加


求一个在C语言环境下进行死锁检测的程序

#include
#include
#include



const int MAXQUEUE=100; //定义表的最大行数



typedef struct node{
int resource;
int process;
}cell;



cell occupy[MAXQUEUE];
int occupy_quantity;
cell wait[MAXQUEUE];
int wait_quantity;




//初始化函数
void initial()
{
int i;



for(i=0;i<MAXQUEUE;i++){
occupy.process=-1;
occupy.resource=-1;



wait.process=-1;
wait.resource=-1;
}
occupy_quantity=0;
wait_quantity=0;
}




//读数据文件
int readData()
{
FILE *fp;
char fname[20];
int i;



cout<<"请输入资源分配表文件的文件名:"<<endl;
strcpy(fname,"10trouble1.txt");
//cin>>fname;
if((fp=fopen(fname,"r"))==NULL){
cout<<"错误,文件打不开,请检查文件名:)"<<endl;
return 0;
}
else{
while(!feof(fp)){
fscanf(fp,"%d %d",&occupy[occupy_quantity].resource,&occupy[occupy_quantity].process);
occupy_quantity++;
}
}



cout<<"请输入进程等待表文件的文件名:"<<endl;
strcpy(fname,"10trouble2.txt");
//cin>>fname;
if((fp=fopen(fname,"r"))==NULL){
cout<<"错误,文件打不开,请检查文件名:)"<<endl;
return 0;
}
else{
while(!feof(fp)){
fscanf(fp,"%d %d",&wait[wait_quantity].process,&wait[wait_quantity].resource);
wait_quantity++;
}
}



//输出所读入的数据
cout<<endl<<endl<<"输出所读入的数据"<<endl;
cout<<"━━━━━━━━━━━━━━━━━━━━━━━"<<endl;
cout<<"资源分配表"<<endl;
cout<<"资源编号 进程编号"<<endl;

for(i=0;i<occupy_quantity;i++){
cout<<" "<<occupy.resource<<" "<<occupy.process<<endl;
}
cout<<"———————————————————————"<<endl;
cout<<"进程等待表"<<endl;
cout<<"进程编号 资源编号"<<endl;

for(i=0;i<wait_quantity;i++){
cout<<" "<<wait.resource<<" "<<wait.process<<endl;
}
return 1;
}




//检测
void check()
{
int table[MAXQUEUE][MAXQUEUE];
int table1[MAXQUEUE][MAXQUEUE];



int i,j,k;
int flag,t,p;
int max_process;




//初始化表格



for(i=0;i<MAXQUEUE;i++){
for(j=0;j<MAXQUEUE;j++){
table[j]=0;
table1[j]=0;
}
}



//先找到进程最大编号
max_process=-1;
for(i=0;i<occupy_quantity;i++){
if(occupy.process>max_process){
max_process=occupy.process;
}
}
for(i=0;i<wait_quantity;i++){
if(wait.process>max_process){
max_process=wait.process;
}
}



for(i=0;i<wait_quantity;i++){
for(j=0;j<occupy_quantity;j++){
if(wait.resource==occupy[j].resource){
table[wait.process][occupy[j].process]=1;
table1[wait.process][occupy[j].process]=1;
}
}
}




cout<<"初始等待占用表:"<<endl;
for(i=0;i<max_process+1;i++){
for(j=0;j<max_process+1;j++){
cout<<table[j]<<" ";
}
cout<<endl;
}



cout<<endl;



for(i=0;i<max_process+1;i++){
for(j=0;j<max_process+1;j++){
for(k=0;k<max_process+1;k++){
table[j]=table[j]||(table[k]&&table[k][j]);
}
}
}
cout<<"检测后的等待占用表:"<<endl;



for(i=0;i<max_process+1;i++){
for(j=0;j<max_process+1;j++){
cout<<table[j]<<" ";
}
cout<<endl;
}



flag=-1;
for(i=0;i<max_process+1;i++){
if(table==1){
flag=i;
break;
}
}
cout<<endl<<endl<<"检测结果"<<endl;
cout<<"———————————————————"<<endl;
if(flag!=-1){
cout<<"存在死锁"<<endl;
cout<<"进程循环等待队列:";



p=flag; //存在进程循环等待队列的那一进程
//进程循环等待队列中的所有进程是table表中的这一行是1的进程,只是顺序要再确定
t=1;
while(t){
cout<<p<<" ";
for(j=0;j<max_process+1;j++){
if(table1[p][j]==1){
if(table[j][flag]==1){
p=j;
break;
}
}
}
if(p==flag)t=0;
}
cout<<flag<<endl;
}
else{
cout<<"不存在死锁"<<endl;
}
}


上一篇:精妆

下一篇:张丹枫