关键部分会在这里工作还是我必须使用信号量或互斥量? [英] Will the critical section work here or should i have to use semaphore or mutex

查看:50
本文介绍了关键部分会在这里工作还是我必须使用信号量或互斥量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是该程序的开始

 #include   "  Derived.h"
  int  main()
{
 for ( int  i =  0 ; i< ; =  2 ; i ++)
{
派生* pDerived =  Derived();
pDerived-> fun();
睡眠( 30000 );
}
返回  0 ;
} 




这是我的意思是基类的接口

 #include   ><   stdlib.h  > 
 #include   <   stdio.h  > 
 #include   <   string.h  > 
 #include   <   process.h  > 
 #include   <   atlstr.h  > 
 #include   <   Windows.h  > 
 #include   <   winsock2.h  > 
 #include   <   ws2tcpip.h  > 
 使用 命名空间 std;
 class 接口
{
公共:
结构 addrinfo addr_;
未签名  port_;
CString hostname_;

HANDLE threadHandle_;
HANDLE threadHandle1_;
布尔 connected_;
SOCKET袜子_;
SOCKET ThreadSocket;
虚拟 无效 fun()=  0 ;
虚拟 DWORD WINAPI MachineConnectThread(接口* my)=  0 ;
虚拟  int  SendRequest(SOCKET sock)=  0 ; // 这会将请求发送到计算机.
虚拟 字符 * ReceiveResponse(SOCKET袜子)=  0 ; // 这将接收来自计算机的二进制数据响应.
HANDLE threadHandle_;

}; 



这是我的派生类

 #include   "  CBase.h"
  class 派生: public 接口
{

公共:
衍生的();
无效 fun();
 int  SendRequest(SOCKET袜子);
字符 * ReceiveResponse(SOCKET sock);
DWORD WINAPI MachineConnectThread(接口* my);
静态 UINT ThreadFunc(LPVOID param);
CRITICAL_SECTION VarCS;
}; 





 #include   "  Derived.h"

派生的:: Derived()
{

sock_ = INVALID_SOCKET;
ThreadSocket = INVALID_SOCKET;

InitializeCriticalSection(&VarCS);

}
无效派生:: fun()
{
printf(" );

// 此处将创建套接字,并将其传递给sebd请求并接收响应功能
尝试 {
DWORD dwThreadId;

threadHandle_ = CreateThread(NULL, 0 ,(LPTHREAD_START_ROUTINE)ThreadFunc, this 捕获(...)
{
如果(threadHandle_ == NULL)
{

printf(" );

返回  0 ;
}
}
}
 int 派生:: SendRequest(SOCKET袜子)
{
printf(" );

}
字符 *派生:: ReceiveResponse(SOCKET袜子)
{
printf(" );
}
UINT派生:: ThreadFunc(LPVOID参数)
{
接口* obj =(接口*)参数;

obj-> MachineConnectThread(obj); // 调用成员函数
// 在新线程中完成工作
返回  0 ;
}
DWORD WINAPI派生:: MachineConnectThread(接口* my)
{
ThreadSocket =(SOCKET)my-> sock_;
同时( 1 )
{
EnterCriticalSection(& VarCS); // 将在此处运行此关键部分
字符 * buf = NULL;
字符 * preBuf = NULL;
 int  i =  0 ;

SendRequest(ThreadSocket);
buf = ReceiveResponse(ThreadSocket);
睡眠( 20000 );
LeaveCriticalSection(&VarCS);
}











} 

解决方案

是的,只要它在一个应用程序中可以运行,
您唯一可以添加的就是使用 DeleteCriticalSection [ ^ ]当您不再需要它时.


您好,您应该仅在主线程中初始化一次临界区.而且,您还必须通过调用DeleteCriticalSection(...);释放其拥有的资源.

 #include   "  Derived.h"
 CRITICAL_SECTION VarCS;
 int  main()
{
    InitializeCriticalSection(&VarCS);
     for ( int  i =  0 ; i< ; =  2 ; i ++)
    {
        派生* pDerived =  Derived();
        pDerived-> fun();
        睡眠( 30000 );
    }
    DeleteCriticalSection(& VarCS);
    返回  0 ;
} 


另外,请尝试考虑使用TryEnterCriticalSection调用而不是EnterCriticalSection调用,它会阻塞您的线程.
如果您计划创建单个流程解决方案,那么关键部分是最佳选择.互斥量和信号量不如关键部分快.请参阅Jeffrey Richter的通过C/C ++的Windows",或参阅MSDN(睡眠( 20000 ); LeaveCriticalSection(& VarCS);


您想在睡觉前离开关键部分.仅在不中断线程执行的关键时才停留在CS中.请参阅
StackOverflow讨论.


This is mine start of the program

#include"Derived.h"
int main()
{
	for(int i=0;i<=2;i++)
	{
		Derived *pDerived=new Derived();
		pDerived->fun();
		Sleep(30000);
	}
	return 0;
}




This is the interface i mean base class

#include <stdlib.h>
#include <stdio.h>
#include <string.h> 
#include <process.h> 
#include<atlstr.h>
#include<Windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
using namespace std; 
class Interface
{
public:
	struct addrinfo    addr_;   
	unsigned short          port_;      
	CString                  hostname_;    
	       
	HANDLE                  threadHandle_;    
	HANDLE                  threadHandle1_;  
	bool                    connected_;     
	SOCKET          sock_; 
	SOCKET ThreadSocket;
	virtual void fun()=0;
	virtual DWORD WINAPI MachineConnectThread(Interface *my)=0;
	virtual int SendRequest(SOCKET sock)=0;      //This will send the request to the machine.
	virtual char* ReceiveResponse(SOCKET sock)=0;  //This will receive the response from the machine that is binary data.
	HANDLE                  threadHandle_;    

};



This is mine derived class

#include"CBase.h"
class Derived:public Interface
{

public:
	Derived();
	void fun();
	int SendRequest(SOCKET sock);
	char* ReceiveResponse(SOCKET sock );
	 DWORD WINAPI MachineConnectThread(Interface *my);
	static UINT ThreadFunc(LPVOID param) ;
	CRITICAL_SECTION	VarCS;
};





#include"Derived.h"

Derived::Derived()
{

	sock_=INVALID_SOCKET;
	ThreadSocket=INVALID_SOCKET;

		InitializeCriticalSection(&VarCS);

}
void Derived::fun()
{
	printf("in fun function\n");

	//Here socket will be created and will be passed to sebd request and receive response function
	try{
	DWORD dwThreadId;

	threadHandle_=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFunc,this,0,&dwThreadId);
}catch(...)
{
	if(threadHandle_ == NULL)
	{

		printf("Error while creating thread.\n");

		return 0;
	}
}
}
int Derived::SendRequest(SOCKET sock)
{
	printf("in this function request will be sent to server\n");

}
char* Derived::ReceiveResponse(SOCKET sock)
{
	printf("here response wil be received from the server\n");
}
UINT Derived::ThreadFunc(LPVOID param)
{
	Interface* obj = (Interface *)param; 

		obj->MachineConnectThread(obj); // call the member function                       
		// to do the work in our new thread
		return 0;
}
DWORD WINAPI Derived::MachineConnectThread(Interface *my)
{
	ThreadSocket=(SOCKET)my->sock_;
	while(1)
	{
		EnterCriticalSection(&VarCS);//WILL THIS CRITICAL SECTION WORK HERE
		char *buf=NULL;
		char* preBuf=NULL;
		int i=0;
		
		SendRequest(ThreadSocket);
		buf=ReceiveResponse(ThreadSocket);
		Sleep(20000);
		LeaveCriticalSection(&VarCS);
	}
		
		
		
		
			
	
		
		
		
		
				
}

解决方案

yes, as long as its inside one application it will work,
the only thing you can add is to use DeleteCriticalSection[^] when you''ll no longer need it.


Hi, you shoud initialize your critical section only once in your main thread. And also you have to free resources it holds by calling DeleteCriticalSection(...);

#include"Derived.h"
CRITICAL_SECTION VarCS;
int main()
{
    InitializeCriticalSection(&VarCS);
    for(int i=0;i<=2;i++)
    {
        Derived *pDerived=new Derived();
        pDerived->fun();
        Sleep(30000);
    }
    DeleteCriticalSection(&VarCS);
    return 0;
}


Also try to consider TryEnterCriticalSection call instead of EnterCriticalSection, which is blocking your thread.
The critical section is the best choice if you plan to create single process solution. Mutexes and semaphores not as fast as critical section. Please see Jeffrey Richter''s "Windows via C/C++", or please refer to MSDN (http://msdn.microsoft.com/en-us/library/windows/desktop/ms682530(v=vs.85).aspx[^])


You have a problem here:

Sleep(20000);
LeaveCriticalSection(&VarCS);


You want to leave the critical section before sleeping. Only stay in the CS while it''s critical that your thread''s execution is not interrupted. See this StackOverflow discussion.


这篇关于关键部分会在这里工作还是我必须使用信号量或互斥量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆