MFC下能不能精确到微秒?

King030609 2010-04-20 11:04:46
MFC下 能不能精确到微秒,有的话请告知函数接口??
...全文
302 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
newasoft 2010-04-29
  • 打赏
  • 举报
回复
可以精确到100-ns
newasoft 2010-04-29
  • 打赏
  • 举报
回复
// mcastSend.cpp : 定义控制台应用程序的入口点。
//
#include <string.h>
#include <winsock2.h> //注意这里的include文件顺序
#include <Ws2tcpip.h>
#include <process.h> //_beginthread要求
#pragma comment(lib, "ws2_32.lib")
#include <iostream>
using namespace std;



#include <windows.h>
#include <iostream>
#include <iomanip>

struct reference_point
{
FILETIME file_time;
LARGE_INTEGER counter;
};

void simplistic_synchronize(reference_point& ref_point);
void get_time(LARGE_INTEGER frequency, const reference_point&
reference, FILETIME& current_time);

static char MULTICAST_IP[20];
static int MULTICAST_PORT;
long packnum;

BOOL m_loopback;
SOCKET server;
static int interval;

char buf15m[1024];
bool stopflag;
static char rev15m[1025];
long m_sendNum;
long m_recNum;
struct threadProc
{
char addr[20];
long port;
#ifdef _WIN32
SOCKET server;
#else
int server;
#endif
int interval;
long packnum;
};
volatile HANDLE _thread_handle; //辅助线程
//DWORD WINAPI sendData(LPVOID lp);
int sendData(LPVOID lp);
int initMcast();
LARGE_INTEGER CoclkQ;
LARGE_INTEGER Counter;
int CPU_Frequency(void); //MHz
void CpuDelayUs(_int64 Us);
int _CPU_FREQ=0;
int main(int argc, char *argv[])
{
packnum = 0;
interval = 0;
_CPU_FREQ = CPU_Frequency(); //利用 CPU 频率初始化定时
memset(buf15m, 61, 1024);
if(argc<=2)
{
memcpy(MULTICAST_IP,"224.0.0.99",11);

MULTICAST_PORT=2002;
interval=20000;
}
else
{
memcpy(MULTICAST_IP,argv[1],20);

MULTICAST_PORT = atoi(argv[2]);

if(argc>=4)
interval = atoi(argv[3]);
if(argc>=5)
{
packnum = atoi(argv[4]);
printf("%d %s:%s %s %s \n",sizeof(argv[1]),argv[1],argv[2],argv[3],argv[4]);
}
}
int g=initMcast();
printf("%d\n",g);
return 0;
}
int initMcast()
{

{
WSAData wsaData;

if( WSAStartup(MAKEWORD(2,2), &wsaData) != 0 )
{
return 0;
}

server = socket(AF_INET, SOCK_DGRAM, 0); //创建一个UDP套接口

int ret ;

const int on = 1; //允许程序的多个实例运行在同一台机器上
ret = setsockopt(server, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
if( ret == SOCKET_ERROR )
{
WSACleanup();

return 1;
}

const int routenum = 10;
ret = setsockopt(server,IPPROTO_IP,IP_MULTICAST_TTL,\
(char*)&routenum,sizeof(routenum));
if( ret == SOCKET_ERROR )
{
WSACleanup();

return 2;
}

const int loopback = 1; //允许回馈
ret = setsockopt(server,IPPROTO_IP,IP_MULTICAST_LOOP,\
(char*)&loopback,sizeof(loopback));
if( ret == SOCKET_ERROR )
{
WSACleanup();

return 3;
}

sockaddr_in local;
memset(&local, 0, sizeof(local));
local.sin_family = AF_INET;
local.sin_port = htons(MULTICAST_PORT);
local.sin_addr.S_un.S_addr = INADDR_ANY;

ret = bind(server, (sockaddr*)(&local), sizeof(local));
if( ret == SOCKET_ERROR )
{
WSACleanup();

return 4;
}

ip_mreq mreq;
memset(&mreq, 0, sizeof(mreq));
mreq.imr_interface.S_un.S_addr = INADDR_ANY;
mreq.imr_multiaddr.S_un.S_addr = inet_addr(MULTICAST_IP);

//加入一个多播组
ret = setsockopt(server,IPPROTO_IP,IP_ADD_MEMBERSHIP,\
(char*)&mreq,sizeof(mreq));
if( ret == SOCKET_ERROR )
{
WSACleanup();

cout<<"IP-"<<MULTICAST_IP<<"Error in setsockopt(IP_ADD_MEMBERSHIP): "<<WSAGetLastError()<<endl;
return 5;
}

//创建线程一个发送多播组数据
struct threadProc mm;
mm.interval=interval;
mm.port=MULTICAST_PORT;
memcpy(mm.addr,MULTICAST_IP,sizeof(MULTICAST_IP));
mm.server=server;
mm.packnum=packnum;
sendData((LPVOID)&mm);
WSACleanup();
}
}
///DWORD WINAPI sendData(LPVOID lp)
typedef struct _BinInt32

{

__int32 i32[2];

} BigInt32;

typedef struct _BigInt64

{

__int64 i64;

} BigInt64;

typedef union _bigInt
{
BigInt32 int32val;
BigInt64 int64val;
} BigInt;
BigInt start_ticks, end_ticks;

void relay(long mi)
{
LONGLONG mk;
QueryPerformanceFrequency(&CoclkQ);
QueryPerformanceCounter(&Counter);

mk=CoclkQ.QuadPart*mi/100000;
_asm {
RDTSC
mov start_ticks.int32val.i32[0], eax
mov start_ticks.int32val.i32[4], edx
}
_asm {
RDTSC
mov end_ticks.int32val.i32[0], eax
mov end_ticks.int32val.i32[4], edx
}
while(mk>=end_ticks.int64val.i64 - start_ticks.int64val.i64 )
{
_asm {
RDTSC
mov end_ticks.int32val.i32[0], eax
mov end_ticks.int32val.i32[4], edx
}
// printf(" %I64Ld \n",end_ticks.int64val.i64 - start_ticks.int64val.i64 );
}
}
int sendData(LPVOID lp)
{
long m_sendNum=0;
printf("ssss\n");
struct threadProc *mp=(threadProc*)lp;
sockaddr_in remote;
memset(&remote, 0, sizeof(remote));
remote.sin_addr.s_addr = inet_addr ( mp->addr );
remote.sin_family = AF_INET ;
remote.sin_port = htons(mp->port);
SYSTEMTIME systime;
char day[200];
char str[50];
reference_point ref_point;
LARGE_INTEGER frequency;
FILETIME file_time;
SYSTEMTIME system_time;
SYSTEMTIME local_time;
_TIME_ZONE_INFORMATION m_zone;
::QueryPerformanceFrequency(&frequency);
simplistic_synchronize(ref_point);
::GetTimeZoneInformation(&m_zone);
while(packnum>=0)
{
get_time(frequency, ref_point, file_time);
::FileTimeToSystemTime(&file_time, &local_time);
::SystemTimeToTzSpecificLocalTime(&m_zone,&local_time,&system_time);
sprintf(str, "%u-%u-%u %u:%u:%u.%03u",
system_time.wYear, system_time.wMonth, system_time.wDay,
system_time.wHour, system_time.wMinute, system_time.wSecond, system_time.wMilliseconds);
sprintf(buf15m,"#%d #T%s %s \r\n",m_sendNum,str,"Simtec mcast start!");
buf15m[strlen(buf15m)-2]='#';
int ret=sendto(mp->server, buf15m, 1024, 0, (sockaddr*)(&remote), sizeof(remote));
//printf("%d \n",m_sendNum);
if(packnum>0)
if(m_sendNum>=packnum-1) {
printf("packnum=%d m_sendNum\n",packnum,m_sendNum);
exit(-1);
}
m_sendNum++;
CpuDelayUs(mp->interval);
}
return 1;
}
int CPU_Frequency(void) //MHz
{
LARGE_INTEGER CurrTicks, TicksCount;
__int64 iStartCounter, iStopCounter;

DWORD dwOldProcessP = GetPriorityClass(GetCurrentProcess());
DWORD dwOldThreadP = GetThreadPriority(GetCurrentThread());

SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);

QueryPerformanceFrequency(&TicksCount);
QueryPerformanceCounter(&CurrTicks);

TicksCount.QuadPart /= 16;
TicksCount.QuadPart += CurrTicks.QuadPart;

_asm
{
rdtsc
mov DWORD PTR iStartCounter, EAX
mov DWORD PTR (iStartCounter+4), EDX
}
while(CurrTicks.QuadPart<TicksCount.QuadPart)
QueryPerformanceCounter(&CurrTicks);

_asm
{
rdtsc
mov DWORD PTR iStopCounter, EAX
mov DWORD PTR (iStopCounter + 4), EDX
}
SetThreadPriority(GetCurrentThread(), dwOldThreadP);
SetPriorityClass(GetCurrentProcess(), dwOldProcessP);

return (int)((iStopCounter-iStartCounter)/62500);
}
void CpuDelayUs(__int64 Us) //利用循环和 CPU 的频率延时, 参数: 微秒
{
__int64 iCounter, iStopCounter;

_asm
{
rdtsc
mov DWORD PTR iCounter, EAX
mov DWORD PTR (iCounter+4), EDX
}
iStopCounter = iCounter + Us*_CPU_FREQ;

while(iStopCounter-iCounter>0)
{
_asm
{
rdtsc
mov DWORD PTR iCounter, EAX
mov DWORD PTR (iCounter+4), EDX
}
}
}
void simplistic_synchronize(reference_point& ref_point)
{
FILETIME ft0 = { 0, 0 },
ft1 = { 0, 0 };
LARGE_INTEGER li;

//
// Spin waiting for a change in system time. Get the matching
// performance counter value for that time.
//
::GetSystemTimeAsFileTime(&ft0);
do
{
::GetSystemTimeAsFileTime(&ft1);
::QueryPerformanceCounter(&li);
}
while ((ft0.dwHighDateTime == ft1.dwHighDateTime) &&
(ft0.dwLowDateTime == ft1.dwLowDateTime));

ref_point.file_time = ft1;
ref_point.counter = li;
}

void get_time(LARGE_INTEGER frequency, const reference_point&
reference, FILETIME& current_time)
{
LARGE_INTEGER li;

::QueryPerformanceCounter(&li);

//
// Calculate performance counter ticks elapsed
//
LARGE_INTEGER ticks_elapsed;

ticks_elapsed.QuadPart = li.QuadPart -
reference.counter.QuadPart;

//
// Translate to 100-nanoseconds intervals (FILETIME
// resolution) and add to
// reference FILETIME to get current FILETIME.
//
ULARGE_INTEGER filetime_ticks,
filetime_ref_as_ul;

filetime_ticks.QuadPart =
(ULONGLONG)((((double)ticks_elapsed.QuadPart/(double)
frequency.QuadPart)*10000000.0)+0.5);
filetime_ref_as_ul.HighPart = reference.file_time.dwHighDateTime;
filetime_ref_as_ul.LowPart = reference.file_time.dwLowDateTime;
filetime_ref_as_ul.QuadPart += filetime_ticks.QuadPart;

//
// Copy to result
//
current_time.dwHighDateTime = filetime_ref_as_ul.HighPart;
current_time.dwLowDateTime = filetime_ref_as_ul.LowPart;
}


newasoft 2010-04-20
  • 打赏
  • 举报
回复
同意4楼观点!!!
King030609 2010-04-20
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 sk_sakula 的回复:]
GetTickCount函数
  函数功能:GetTickCount返回(retrieve)从操作系统启动到现在所经过(elapsed)的毫秒数,它的返回值是DWORD
[/Quote]什么意思??
sk_sakula 2010-04-20
  • 打赏
  • 举报
回复
GetTickCount函数
  函数功能:GetTickCount返回(retrieve)从操作系统启动到现在所经过(elapsed)的毫秒数,它的返回值是DWORD
jingzhongrong 2010-04-20
  • 打赏
  • 举报
回复
QueryPerformanceCounter、QueryPerformanceFrequency
ls2141 2010-04-20
  • 打赏
  • 举报
回复
SYSTEMTIME 可以取到Milliseconds
如果求间隔可以用ctimespan自己算
King030609 2010-04-20
  • 打赏
  • 举报
回复
回复楼上的
GetTickCount函数
  函数功能:GetTickCount返回(retrieve)从操作系统启动到现在所经过(elapsed)的毫秒数,它的返回值是DWORD
kier2 2010-04-20
  • 打赏
  • 举报
回复
GetTickCount
The GetTickCount function retrieves the number of milliseconds that have elapsed since the system was started. It is limited to the resolution of the system timer. To obtain the system timer resolution, use the GetSystemTimeAdjustment function.

DWORD GetTickCount(VOID);

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧