C+中的异步线程+; 我们使用Visual Studio 2005开发一个游戏(我们的一些计算机仍然运行Windows 2000,这是最新的版本,它将运行,我们不能很容易地将它转换成新版本)C++。

C+中的异步线程+; 我们使用Visual Studio 2005开发一个游戏(我们的一些计算机仍然运行Windows 2000,这是最新的版本,它将运行,我们不能很容易地将它转换成新版本)C++。,c++,multithreading,visual-studio,visual-c++,C++,Multithreading,Visual Studio,Visual C++,我们的音乐制作人已经编写了一些短曲目来测试系统,但出现了一个问题: 游戏在播放音乐或音效时冻结 虽然这对SFX来说不是一个特别大的问题,但音乐是一个非常大的问题,因为我们需要它在后台运行 我想我们可能可以在后台创建第二个线程或进程,在循环中播放指定的曲目,但当我搜索时,我找不到任何适用于此的方法,因为两个进程之间需要进行数据传输(尽管是单向的) 我看到的,我们应该能够从一个包含轨道号码的主程序传递一个命令到音乐进程,这应该相当简单,但是我们最近移动到C++,而且对它目前还不太有经验。 谢谢你的建

我们的音乐制作人已经编写了一些短曲目来测试系统,但出现了一个问题:
游戏在播放音乐或音效时冻结

虽然这对SFX来说不是一个特别大的问题,但音乐是一个非常大的问题,因为我们需要它在后台运行

我想我们可能可以在后台创建第二个线程或进程,在循环中播放指定的曲目,但当我搜索时,我找不到任何适用于此的方法,因为两个进程之间需要进行数据传输(尽管是单向的)

我看到的,我们应该能够从一个包含轨道号码的主程序传递一个命令到音乐进程,这应该相当简单,但是我们最近移动到C++,而且对它目前还不太有经验。 谢谢你的建议

另外,请不要评论我们使用过时的软件,我们这样做是为了好玩,根本不打算投入任何资金

编辑:为清楚起见,如果不清楚我们是否都在运行Windows,并且不打算将其移植到任何其他平台-我们正在运行Visual Studio 2005,但计划是一旦我们能够获得适当的光盘和软件,就开始迁移到Visual Studio 2008或2010 Ultimate

除了嘟嘟声,音乐什么也不用做;命令内置于标准Windows头文件(Windows.h)中

我们想运行一个与主程序并行的二级进程,以便播放背景音乐


如果两个进程之间的数据传输太困难,我们是否能够在它打开时将一个起始变量作为曲目号传递给它,并在它完成时简单地将其终止?

对于Visual Studio,声明为volatile的变量将包括内存围栏操作(除非关闭此选项,否则默认情况下它处于启用状态),允许在线程之间使用它们。鉴于此,代码可以使用一个可变变量来播放音乐曲目。我在下面包含了示例C代码

我假设在播放音乐时,Beep()不会受cpu限制(它似乎不适用于Windows XP)

为了获得更精确的计时,可以使用timeBeginPeriod()将计时器频率从64hz(15.625毫秒)增加到1000hz(1毫秒)。在Windows XP和Windows 2000的情况下,timeBeginPeriod(1)会使计时器实际运行在1024hz,而Sleep()和my guess Beep()会使计时器运行在1024hz模拟1000hz的滴答声,每128滴答声添加3个额外的实际滴答声,以达到125ms的边界。这意味着睡眠(1)有时可能需要将近2ms的时间(在42、84和125次通话中)

注意-最终,由于缺少与之通信的硬件,Windows Vista和Windows XP 64位版本中不再支持蜂鸣音。在Windows 7中,蜂鸣音被重写,以将蜂鸣音传递给会话的默认声音设备。这通常是声卡,但在终端服务下运行时除外,在这种情况下蜂鸣音为ren委托人委托的

示例多线程“嘟嘟”代码。此代码在Windows XP上使用PC扬声器,与预期一样工作。在Windows 7上,它使用声卡,音符之间有一些静音

/*----------------------------------------------------------------------*/
/*      mtbeep.c        multi-thread beep demo                          */
/*----------------------------------------------------------------------*/
#include <windows.h>
/* include winmm.lib for timeBeginPeriod */
#pragma comment(lib, "winmm.lib")

#define TRACK0 0
#define TRACK1 1
#define TRACK2 2
#define TRACKX 3                       /* exit thread 1 if trackx */

typedef struct {
    DWORD dwFreq;
    DWORD dwDuration;
}NOTE;

/*----------------------------------------------------------------------*/
/*      data                                                            */
/*----------------------------------------------------------------------*/
static HANDLE   htT1;                   /* thread 1 handle */
static DWORD    dwThreadT1;             /* thread id's (not used) */

static volatile DWORD dwTrack;          /* beep track to play */

/* songs */
static NOTE     anTrack0[4] = {300, 500, 450, 500, 600, 500, 0, 0};
static NOTE     anTrack1[4] = {  0, 250};
static NOTE     anTrack2[4] = {400, 500, 300, 500, 200, 500, 0, 0};
static NOTE     anTrackx[4] = {0, 0};

/*----------------------------------------------------------------------*/
/*      code                                                            */
/*----------------------------------------------------------------------*/
static DWORD    WINAPI Thread0(LPVOID);
static DWORD    WINAPI Thread1(LPVOID);
/*----------------------------------------------------------------------*/
/*      main                                                            */
/*----------------------------------------------------------------------*/
DWORD main(DWORD argc, BYTE **argv)
{
    timeBeginPeriod(1);                 /* set period to 1ms */
    Sleep(128);                         /* wait for it to stabilize */

    /*  create thread */
    htT1 = CreateThread(NULL, 0, Thread1, 0, 0, &dwThreadT1);
    if(!htT1){
        /* createthread failed */
        goto exit0;}
    Thread0((LPVOID)NULL);              /* start Thread 0 */
exit0:
    if(htT1){                           /* close thread */
        dwTrack = TRACKX;
        WaitForSingleObject(htT1, INFINITE);
        CloseHandle(htT1);}
    timeEndPeriod(1);                   /* restore period */
    return(0);
}

/*----------------------------------------------------------------------*/
/*      Thread0                                                         */
/*----------------------------------------------------------------------*/
static DWORD WINAPI Thread0(LPVOID lpvoid)
{
int i;
    for(i = 0; i < 4; i++){
        dwTrack = i%3;
        Sleep(5000);
    }
    return 0;
}

/*----------------------------------------------------------------------*/
/*      Thread1         beep thread                                     */
/*----------------------------------------------------------------------*/
static DWORD WINAPI Thread1(LPVOID lpvoid)
{
NOTE *apTrack[4] = {anTrack0, anTrack1, anTrack2, anTrackx};
NOTE *pTrack = anTrack0;                /* ptr to array of notes */
DWORD cTrack = TRACKX;                  /* current track */
int iNote = 0;                          /* note index */

    while(dwTrack != TRACKX){           /* play a note loop */
        if(cTrack != dwTrack){          /* if song changed */
            iNote = 0;                  /*  start at first note */
            cTrack = dwTrack;           /*  of next song */
            pTrack = apTrack[cTrack];
        }
        if(!pTrack[iNote].dwDuration)   /* if end of song */
            iNote = 0;                  /*  reset note index */
        if(pTrack[iNote].dwFreq)        /* if note play it */
            Beep(pTrack[iNote].dwFreq, pTrack[iNote].dwDuration);
        else                            /* else silence */
            Sleep(pTrack[iNote].dwDuration);
        iNote++;
    }
    return(0);
}
/*----------------------------------------------------------------------*/
/*c多线程蜂鸣演示*/
/*----------------------------------------------------------------------*/
#包括
/*包含timeBeginPeriod的winmm.lib*/
#pragma注释(lib,“winmm.lib”)
#定义跟踪0
#定义TRACK1 1
#定义TRACK2
#定义TRACKX 3/*如果TRACKX*/
类型定义结构{
德沃德·德弗雷;
德沃德·德沃德;
}注;
/*----------------------------------------------------------------------*/
/*资料*/
/*----------------------------------------------------------------------*/
静态句柄htT1;/*线程1句柄*/
静态DWORD dwThreadT1;/*线程id(未使用)*/
静态易失性DWORD dwTrack;/*播放嘟嘟声曲目*/
/*歌曲*/
静态注释anTrack0[4]={300500450500600500,0,0};
静态注释anTrack1[4]={0250};
静态注释anTrack2[4]={400500300500200500,0,0};
静态注释anTrackx[4]={0,0};
/*----------------------------------------------------------------------*/
/*代码*/
/*----------------------------------------------------------------------*/
静态DWORD WINAPI线程0(LPVOID);
静态DWORD WINAPI线程1(LPVOID);
/*----------------------------------------------------------------------*/
/*主要*/
/*----------------------------------------------------------------------*/
DWORD main(DWORD argc,字节**argv)
{
timeBeginPeriod(1);/*将时段设置为1ms*/
睡眠(128);/*等待它稳定下来*/
/*创建线程*/
htT1=CreateThread(NULL、0、Thread1、0、0和dwThreadT1);
如果(!htT1){
/*createthread失败*/
转到exit0;}
线程0((LPVOID)NULL);/*开始线程0*/
出口:
如果(htT1){/*关闭线程*/
dwTrack=TRACKX;
WaitForSingleObject(htT1,无限);
CloseHandle(htT1);}
timeEndPeriod(1);/*恢复期*/
返回(0);
}
/*----------------------------------------------------------------------*/
/*线程0*/
/*------------------------------------------------------------------