求助!c语言创建线程未运行问题

顾染尘 2021-05-26 04:44:17
代码如下

ULONG _stdcall ThreadFunc1( LPVOID lpParam ) {
AfxMessageBox(_T("ThreadFunc1"));
static int nCount; //产生事件的次数
while(g_keepRunning)
{
//只要事件列表中有一个事件有信号,就结束等待
ULONG RetForWait = 0xffffffff;
RetForWait = WaitForSingleObject(g_hEventSFIFO,INFINITE);
if( RetForWait == WAIT_OBJECT_0 )
{
CString tempStr;
CSFDJController1Dlg* curDlg;
curDlg = (CSFDJController1Dlg*)AfxGetApp()->m_pMainWnd;
//显示进入事件的次数
nCount++;
tempStr.Format(_T("事件次数: %d"), nCount);
// curDlg->SetDlgItemText( IDC_LBL_COUNT, tempStr );
long retCount; //,i;
//还是要判断一下才能读,因为此时真正的数据个数可能不到需要的数
tempStr.Format(_T("SFIFO中数据个数: %d"), ZT8348_GetSFifoDataCount(g_cardNO,1));
//curDlg->SetDlgItemText( IDC_LBL_DATA_COUNT, tempStr );
//ZT8348_GetSFifoDataCount得到驱动缓冲区(SFIFO)中当前有效数据的个数
if( ZT8348_GetSFifoDataCount(g_cardNO,1) >= g_wantCount )
{
//ZT8348_AISFifo定时启动AD或外触发启动AD时,从驱动缓冲区(SFIFO)中读一批数 g_wantCount希望得到的个数
retCount = ZT8348_AISFifo(g_cardNO, 0, g_resultArr, g_wantCount);//g_resultArr采集结果
//显示前8个数
//g_resultArr[i] = 1000.0;
//每次求平均值个数为30000个,每次间隔100个值
ZT8348_AISFifoChAver(g_cardNO, 0,g_resultArr,30000,100);

//ZT8348_AISFifoChAver函数只支持单通道 ,目前状态是1通道值为0,使用2通道,求平均值的时候就需要乘以两倍

float gaiv = (g_resultArr[1]*2)/(float)1000;//转换单位 将mv转换为v
float gaimv = (g_resultArr[1]*2);
tempStr.Format(_T("%7.3f v"), gaimv);//总共七位 其中两位小数点
curDlg->SetDlgItemText(IDC_LBL_AD1+0, tempStr);

float kg = 38.18*gaiv;//36.28五个点位求出的平均值
tempStr.Format(_T("%7.2f KG"), kg);//总共七位 其中两位小数点

curDlg->SetDlgItemText(IDC_LBL_AD0+0, tempStr);

PYali=g_resultArr[1];
/*如果 压力值减去标准值是区间范围*/
float ca = PYali-chazhi;
if(ca<=2){
// AfxMessageBox(_T("获取稳定压力值的次数 "));
countaaa++;
}
if(countaaa>3){
// PYalir=PYali;
PYalia(kg);
}
chazhi=PYali;

}
}
}
return 0;
}


float StartCaijiwd(){
cunya=0;
// AfxMessageBox(_T("开始采集无参数"));
//新建文件
if( (g_fp=(fopen("wending.dat","wb")))==NULL)
{
AfxMessageBox(_T("open file failed"));
return -1;
}
// AfxMessageBox("PYali");
//建立一个线程监视事件
DWORD dwThreadId;
HANDLE hThread;
g_keepRunning = 1;
hThread = CreateThread(NULL,0,ThreadFunc1,NULL,0,&dwThreadId);
if (hThread == NULL)
{
AfxMessageBox(_T("CreateThread failed\n"));
}
else
{
CloseHandle( hThread );
}

//启动AD
ZT8348_DisableAD(g_cardNO); //停止定时AD
ZT8348_ClearHFifo(g_cardNO, 1); //清空硬件FIFO(HFIFO)
ZT8348_ClearSFifo(g_cardNO, 1); //清空软件FIFO(SFIFO)
if( ZT8348_GetSFifoSize(g_cardNO, 1) != 2000 )
{
if( ZT8348_SetSFifoSize(g_cardNO, 1, 2000) != 2000 )
{
CString tempStr1;
tempStr1.Format(_T("g_cardNO: %d"), g_cardNO);
AfxMessageBox(tempStr1);
AfxMessageBox(_T("未申请到足够的缓冲区"));
CString tempStr;
tempStr.Format(_T("错误号: %d"), ZT8348_GetLastErr());
AfxMessageBox(tempStr);

return -1;
}
}

g_wantCount = 1024000;//200000;
ZT8348_SetSFifoThreshold(g_cardNO, 1, g_wantCount); //设置SFIFO阀值
//打开中断,注意HFIFO超过半满时打开中断会死机
//建立一个事件
g_hEventSFIFO = CreateEvent(NULL,false,false,NULL);
if( (HANDLE)g_hEventSFIFO != NULL )
ZT8348_OpenIRQ(g_cardNO, (long)g_hEventSFIFO, 0); //打开中断

ULONG AIRangeArr[8];
ULONG ampInxArr[8];
//不能用,因为并未把所有元素初始化为2,ULONG AIRangeArr[8] = {2};
//ULONG ampInxArr[8] = {0};
//公式:采样频率= 16000000Hz/(分频系数+1)
const ULONG ADinClock = 16000000;
ULONG ADfreq = 500000;//分频系数
ULONG ADstartModeWord = 1; //定时启动
ULONG i;
//量程为 -10~+10V
for(i=0; i<8; i++)
{//2 : 0-- +10000mV
AIRangeArr[i] = 2;// 6;//按照 -10000 -- +10000mV 量程装入零 点和满度值,必须与板卡的实际跳线相一致
ampInxArr[i] = 0;
}

ZT8348_AIinit(g_cardNO, 0, 2, AIRangeArr, ampInxArr, ADstartModeWord, ADinClock / ADfreq - 1, 0, 0);
ZT8348_EnableAD(g_cardNO); //启动定时AD

//返回函数执行的状态
CString tempStr;
tempStr.Format(_T("错误号: %d"), ZT8348_GetLastErr());

/*PYali是在取值区间范围内返回触发停止采集*/
//AfxMessageBox("2333333");
// float att = 5000;
// Sleep(3000);
while(0.02){
Sleep(6000);
if(cunya>0){
// AfxMessageBox(_T("成功获取压力值"));
return cunya;
}
// AfxMessageBox(_T("等待2秒获取稳定压力值"));
}

// return 0;
}

void StopCaiji(){
//停止采集
fclose(g_fp);//关闭
ZT8348_CloseIRQ(g_cardNO); //关闭中断
//返回函数执行的状态
CString tempStr;
tempStr.Format(_T("错误号: %d"), ZT8348_GetLastErr());


g_keepRunning = 0;
if( (HANDLE)g_hEventSFIFO != NULL )
{
if( CloseHandle( g_hEventSFIFO ) != 0L )
{
g_hEventSFIFO = NULL;
AfxMessageBox(_T("关闭采集"));
}
}

return ;
}



使用MFC按钮功能调用StartCaiji(a)函数,呈现卡死状态,使用弹框发现创建第一个线程ThreadFunc并没有被执行,然后一直走下面的while(a)方法,在while(a)方法上sleep也不能让ThreadFunc函数执行,不知道要怎么解决,请问有什么解决办法吗?
...全文
555 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2021-05-27
  • 打赏
  • 举报
回复
主程序和线程共享全局变量,将读写该全局变量的语句放在我上面代码中的Lock和Unlock之间。
赵4老师 2021-05-27
  • 打赏
  • 举报
回复
看其中带“★”的行:

ULONG _stdcall ThreadFunc1( LPVOID lpParam ) {
    AfxMessageBox(_T("ThreadFunc1"));
    static int nCount; //产生事件的次数
    while(g_keepRunning)
    {
        //只要事件列表中有一个事件有信号,就结束等待
        ULONG RetForWait = 0xffffffff;
        RetForWait = WaitForSingleObject(g_hEventSFIFO,INFINITE);
        if( RetForWait == WAIT_OBJECT_0 )
        {
            CString tempStr;
            CSFDJController1Dlg* curDlg;
            curDlg = (CSFDJController1Dlg*)AfxGetApp()->m_pMainWnd;
            //显示进入事件的次数
            nCount++;
            tempStr.Format(_T("事件次数: %d"), nCount);
        //  curDlg->SetDlgItemText( IDC_LBL_COUNT, tempStr );
            long retCount; //,i;
            //还是要判断一下才能读,因为此时真正的数据个数可能不到需要的数
            tempStr.Format(_T("SFIFO中数据个数: %d"), ZT8348_GetSFifoDataCount(g_cardNO,1));
            //curDlg->SetDlgItemText( IDC_LBL_DATA_COUNT, tempStr );
            //ZT8348_GetSFifoDataCount得到驱动缓冲区(SFIFO)中当前有效数据的个数
            if( ZT8348_GetSFifoDataCount(g_cardNO,1) >= g_wantCount )
            {
                //ZT8348_AISFifo定时启动AD或外触发启动AD时,从驱动缓冲区(SFIFO)中读一批数 g_wantCount希望得到的个数
                retCount = ZT8348_AISFifo(g_cardNO, 0, g_resultArr, g_wantCount);//g_resultArr采集结果
                //显示前8个数
                 //g_resultArr[i] = 1000.0;
                //每次求平均值个数为30000个,每次间隔100个值
                ZT8348_AISFifoChAver(g_cardNO, 0,g_resultArr,30000,100);

                //ZT8348_AISFifoChAver函数只支持单通道 ,目前状态是1通道值为0,使用2通道,求平均值的时候就需要乘以两倍

                float gaiv = (g_resultArr[1]*2)/(float)1000;//转换单位 将mv转换为v
                float gaimv = (g_resultArr[1]*2);
                tempStr.Format(_T("%7.3f v"), gaimv);//总共七位 其中两位小数点
                curDlg->SetDlgItemText(IDC_LBL_AD1+0, tempStr);

                float kg = 38.18*gaiv;//36.28五个点位求出的平均值
                tempStr.Format(_T("%7.2f KG"), kg);//总共七位 其中两位小数点

                curDlg->SetDlgItemText(IDC_LBL_AD0+0, tempStr);

                PYali=g_resultArr[1];
                /*如果 压力值减去标准值是区间范围*/
                float ca = PYali-chazhi;
                if(ca<=2){
                //  AfxMessageBox(_T("获取稳定压力值的次数 "));
                    countaaa++;
                }
                if(countaaa>3){
                //  PYalir=PYali;
                    PYalia(kg);
                }
                chazhi=PYali;

            }
        }
    }
    return 0;
}


float  StartCaijiwd(){
    cunya=0;
//  AfxMessageBox(_T("开始采集无参数"));
    //新建文件
    if( (g_fp=(fopen("wending.dat","wb")))==NULL)
    {
        AfxMessageBox(_T("open file failed"));
        return -1;
    }
//  AfxMessageBox("PYali");
    //建立一个线程监视事件
    DWORD dwThreadId;
    HANDLE hThread;

    g_hEventSFIFO = CreateEvent(NULL,false,false,NULL);//★zhao4zhong1 因为ThreadFunc1中使用了g_hEventSFIF,所以这句应挪到CreateThread之前
    if( (HANDLE)g_hEventSFIFO == NULL ) {
        AfxMessageBox(_T("CreateEvent failed\n"));
        return -1;
    }

    g_keepRunning = 1;
    hThread = CreateThread(NULL,0,ThreadFunc1,NULL,0,&dwThreadId);
    if (hThread == NULL)
    {
      AfxMessageBox(_T("CreateThread failed\n"));
    }
    else
    {
      CloseHandle( hThread );
    }

    //启动AD
    ZT8348_DisableAD(g_cardNO); //停止定时AD
    ZT8348_ClearHFifo(g_cardNO, 1); //清空硬件FIFO(HFIFO)
    ZT8348_ClearSFifo(g_cardNO, 1); //清空软件FIFO(SFIFO)
    if( ZT8348_GetSFifoSize(g_cardNO, 1) != 2000 )
    {
        if( ZT8348_SetSFifoSize(g_cardNO, 1, 2000) != 2000 )
        {
            CString tempStr1;
            tempStr1.Format(_T("g_cardNO: %d"), g_cardNO);
            AfxMessageBox(tempStr1);
            AfxMessageBox(_T("未申请到足够的缓冲区"));
            CString tempStr;
            tempStr.Format(_T("错误号: %d"), ZT8348_GetLastErr());
            AfxMessageBox(tempStr);

            return -1;
        }
    }

    g_wantCount = 1024000;//200000;
    ZT8348_SetSFifoThreshold(g_cardNO, 1, g_wantCount); //设置SFIFO阀值
    //打开中断,注意HFIFO超过半满时打开中断会死机
    //建立一个事件
//  g_hEventSFIFO = CreateEvent(NULL,false,false,NULL);//★zhao4zhong1 因为ThreadFunc1中使用了g_hEventSFIF,所以这句应挪到CreateThread之前
    if( (HANDLE)g_hEventSFIFO != NULL )
        ZT8348_OpenIRQ(g_cardNO, (long)g_hEventSFIFO, 0); //打开中断

    ULONG AIRangeArr[8];
    ULONG ampInxArr[8];
    //不能用,因为并未把所有元素初始化为2,ULONG AIRangeArr[8] = {2};
    //ULONG ampInxArr[8] = {0};
    //公式:采样频率= 16000000Hz/(分频系数+1)
    const ULONG ADinClock = 16000000;
    ULONG ADfreq = 500000;//分频系数
    ULONG ADstartModeWord = 1; //定时启动
    ULONG i;
    //量程为 -10~+10V
    for(i=0; i<8; i++)
    {//2 :  0-- +10000mV
        AIRangeArr[i] = 2;// 6;//按照 -10000 -- +10000mV 量程装入零 点和满度值,必须与板卡的实际跳线相一致
        ampInxArr[i] = 0;
    }

    ZT8348_AIinit(g_cardNO, 0, 2, AIRangeArr, ampInxArr, ADstartModeWord, ADinClock / ADfreq - 1, 0, 0);
    ZT8348_EnableAD(g_cardNO); //启动定时AD

    //返回函数执行的状态
    CString tempStr;
    tempStr.Format(_T("错误号: %d"), ZT8348_GetLastErr());

    /*PYali是在取值区间范围内返回触发停止采集*/
    //AfxMessageBox("2333333");
//  float att = 5000;
//  Sleep(3000);
    while(0.02){
        Sleep(6000);
        if(cunya>0){
        //  AfxMessageBox(_T("成功获取压力值"));
            return cunya;
        }
    //  AfxMessageBox(_T("等待2秒获取稳定压力值"));
    }

//  return 0;
}

void StopCaiji(){
    //停止采集
    fclose(g_fp);//关闭
    ZT8348_CloseIRQ(g_cardNO); //关闭中断
    //返回函数执行的状态
    CString tempStr;
    tempStr.Format(_T("错误号: %d"), ZT8348_GetLastErr());


    g_keepRunning = 0;
    if( (HANDLE)g_hEventSFIFO != NULL )
    {
        if( CloseHandle( g_hEventSFIFO ) != 0L )
        {
            g_hEventSFIFO = NULL;
            AfxMessageBox(_T("关闭采集"));
        }
    }

    return ;
}

顾染尘 2021-05-27
  • 打赏
  • 举报
回复
引用 2 楼 赵4老师 的回复:
仅供参考:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _MSC_VER
    #include <windows.h>
    #include <io.h>
    #include <process.h>
    #define  MYVOID             void
#else
    #include <unistd.h>
    #include <sys/time.h>
    #include <pthread.h>
    #define  CRITICAL_SECTION   pthread_mutex_t
    #define  _vsnprintf         vsnprintf
    #define  MYVOID             void *
#endif
//Log{
#define MAXLOGSIZE 20000000
#define ARRSIZE(x) (sizeof(x)/sizeof(x[0]))
#include <time.h>
#include <sys/timeb.h>
#include <stdarg.h>
char logfilename1[]="MyLog1.log";
char logfilename2[]="MyLog2.log";
char logstr[16000];
char datestr[16];
char timestr[16];
char mss[4];
CRITICAL_SECTION cs_log;
FILE *flog;
#ifdef _MSC_VER
void Lock(CRITICAL_SECTION *l) {
    EnterCriticalSection(l);
}
void Unlock(CRITICAL_SECTION *l) {
    LeaveCriticalSection(l);
}
void sleep_ms(int ms) {
    Sleep(ms);
}
#else
void Lock(CRITICAL_SECTION *l) {
    pthread_mutex_lock(l);
}
void Unlock(CRITICAL_SECTION *l) {
    pthread_mutex_unlock(l);
}
void sleep_ms(int ms) {
    usleep(ms*1000);
}
#endif
void LogV(const char *pszFmt,va_list argp) {
    struct tm *now;
    struct timeb tb;


    if (NULL==pszFmt||0==pszFmt[0]) return;
    if (-1==_vsnprintf(logstr,ARRSIZE(logstr),pszFmt,argp)) logstr[ARRSIZE(logstr)-1]=0;
    ftime(&tb);
    now=localtime(&tb.time);
    sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);
    sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );
    sprintf(mss,"%03d",tb.millitm);
    printf("%s %s.%s %s",datestr,timestr,mss,logstr);
    flog=fopen(logfilename1,"a");
    if (NULL!=flog) {
        fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);
        if (ftell(flog)>MAXLOGSIZE) {
            fclose(flog);
            if (rename(logfilename1,logfilename2)) {
                remove(logfilename2);
                rename(logfilename1,logfilename2);
            }
            flog=fopen(logfilename1,"a");
            if (NULL==flog) return;
        }
        fclose(flog);
    }
}
void Log(const char *pszFmt,...) {
    va_list argp;

    Lock(&cs_log);
    va_start(argp,pszFmt);
    LogV(pszFmt,argp);
    va_end(argp);
    Unlock(&cs_log);
}
//Log}
int No_Loop=0;
MYVOID testThread(void *pcn) {
    int n,i;

    n=(int)pcn;
    i=0;
    while (1) {
        sleep_ms(1000);
        Log("in testThread %d:i==%ds\n",n,++i);
        if (i>=5) No_Loop=1;
    }
}
int main(int argc,char * argv[]) {
    int i;
#ifdef _MSC_VER
    InitializeCriticalSection(&cs_log);
#else
    pthread_mutex_init(&cs_log,NULL);
    pthread_t threads[1];
    int threadsN;
    int rc;
#endif
    Log("=========BEGIN==================\n");
#ifdef _MSC_VER
    _beginthread((void(__cdecl *)(void *))testThread,0,(void *)1);
#else
    threadsN=0;
    rc=pthread_create(&(threads[threadsN++]),NULL,testThread,(void *)1);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);
#endif
    i=0;
    while (1) {
        sleep_ms(100);
        Log("in main:i==%d\n",++i);
        if (No_Loop==1) break;//
    }
    Log("=========END====================\n");
#ifdef _MSC_VER
    DeleteCriticalSection(&cs_log);
#else
    pthread_mutex_destroy(&cs_log);
#endif
    return 0;
}
//2012-06-14 16:27:21.500 =========BEGIN==================
//2012-06-14 16:27:21.609 in main:i==1
//2012-06-14 16:27:21.718 in main:i==2
//2012-06-14 16:27:21.828 in main:i==3
//2012-06-14 16:27:21.937 in main:i==4
//2012-06-14 16:27:22.046 in main:i==5
//2012-06-14 16:27:22.156 in main:i==6
//2012-06-14 16:27:22.265 in main:i==7
//2012-06-14 16:27:22.375 in main:i==8
//2012-06-14 16:27:22.484 in main:i==9
//2012-06-14 16:27:22.500 in testThread 1:i==1s
//2012-06-14 16:27:22.593 in main:i==10
//2012-06-14 16:27:22.703 in main:i==11
//2012-06-14 16:27:22.812 in main:i==12
//2012-06-14 16:27:22.921 in main:i==13
//2012-06-14 16:27:23.031 in main:i==14
//2012-06-14 16:27:23.140 in main:i==15
//2012-06-14 16:27:23.250 in main:i==16
//2012-06-14 16:27:23.359 in main:i==17
//2012-06-14 16:27:23.468 in main:i==18
//2012-06-14 16:27:23.500 in testThread 1:i==2s
//2012-06-14 16:27:23.578 in main:i==19
//2012-06-14 16:27:23.687 in main:i==20
//2012-06-14 16:27:23.796 in main:i==21
//2012-06-14 16:27:23.906 in main:i==22
//2012-06-14 16:27:24.015 in main:i==23
//2012-06-14 16:27:24.125 in main:i==24
//2012-06-14 16:27:24.234 in main:i==25
//2012-06-14 16:27:24.343 in main:i==26
//2012-06-14 16:27:24.453 in main:i==27
//2012-06-14 16:27:24.500 in testThread 1:i==3s
//2012-06-14 16:27:24.562 in main:i==28
//2012-06-14 16:27:24.671 in main:i==29
//2012-06-14 16:27:24.781 in main:i==30
//2012-06-14 16:27:24.890 in main:i==31
//2012-06-14 16:27:25.000 in main:i==32
//2012-06-14 16:27:25.109 in main:i==33
//2012-06-14 16:27:25.218 in main:i==34
//2012-06-14 16:27:25.328 in main:i==35
//2012-06-14 16:27:25.437 in main:i==36
//2012-06-14 16:27:25.500 in testThread 1:i==4s
//2012-06-14 16:27:25.546 in main:i==37
//2012-06-14 16:27:25.656 in main:i==38
//2012-06-14 16:27:25.765 in main:i==39
//2012-06-14 16:27:25.875 in main:i==40
//2012-06-14 16:27:25.984 in main:i==41
//2012-06-14 16:27:26.093 in main:i==42
//2012-06-14 16:27:26.203 in main:i==43
//2012-06-14 16:27:26.312 in main:i==44
//2012-06-14 16:27:26.421 in main:i==45
//2012-06-14 16:27:26.500 in testThread 1:i==5s
//2012-06-14 16:27:26.531 in main:i==46
//2012-06-14 16:27:26.531 =========END====================
问个问题,之前的程序是执行了的,但是卡死不是因为第一个线程,是因为第二个while,我想取得第一个线程产生的某个值,我现在把线程需要的值赋值到了一个全局变量上,但是 我不知道要怎么在创建此线程的下面,接着不断地获取到那个全局变量的值,请问有什么解决办法吗?
赵4老师 2021-05-27
  • 打赏
  • 举报
回复
仅供参考:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _MSC_VER
    #include <windows.h>
    #include <io.h>
    #include <process.h>
    #define  MYVOID             void
#else
    #include <unistd.h>
    #include <sys/time.h>
    #include <pthread.h>
    #define  CRITICAL_SECTION   pthread_mutex_t
    #define  _vsnprintf         vsnprintf
    #define  MYVOID             void *
#endif
//Log{
#define MAXLOGSIZE 20000000
#define ARRSIZE(x) (sizeof(x)/sizeof(x[0]))
#include <time.h>
#include <sys/timeb.h>
#include <stdarg.h>
char logfilename1[]="MyLog1.log";
char logfilename2[]="MyLog2.log";
char logstr[16000];
char datestr[16];
char timestr[16];
char mss[4];
CRITICAL_SECTION cs_log;
FILE *flog;
#ifdef _MSC_VER
void Lock(CRITICAL_SECTION *l) {
    EnterCriticalSection(l);
}
void Unlock(CRITICAL_SECTION *l) {
    LeaveCriticalSection(l);
}
void sleep_ms(int ms) {
    Sleep(ms);
}
#else
void Lock(CRITICAL_SECTION *l) {
    pthread_mutex_lock(l);
}
void Unlock(CRITICAL_SECTION *l) {
    pthread_mutex_unlock(l);
}
void sleep_ms(int ms) {
    usleep(ms*1000);
}
#endif
void LogV(const char *pszFmt,va_list argp) {
    struct tm *now;
    struct timeb tb;


    if (NULL==pszFmt||0==pszFmt[0]) return;
    if (-1==_vsnprintf(logstr,ARRSIZE(logstr),pszFmt,argp)) logstr[ARRSIZE(logstr)-1]=0;
    ftime(&tb);
    now=localtime(&tb.time);
    sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);
    sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );
    sprintf(mss,"%03d",tb.millitm);
    printf("%s %s.%s %s",datestr,timestr,mss,logstr);
    flog=fopen(logfilename1,"a");
    if (NULL!=flog) {
        fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);
        if (ftell(flog)>MAXLOGSIZE) {
            fclose(flog);
            if (rename(logfilename1,logfilename2)) {
                remove(logfilename2);
                rename(logfilename1,logfilename2);
            }
            flog=fopen(logfilename1,"a");
            if (NULL==flog) return;
        }
        fclose(flog);
    }
}
void Log(const char *pszFmt,...) {
    va_list argp;

    Lock(&cs_log);
    va_start(argp,pszFmt);
    LogV(pszFmt,argp);
    va_end(argp);
    Unlock(&cs_log);
}
//Log}
int No_Loop=0;
MYVOID testThread(void *pcn) {
    int n,i;

    n=(int)pcn;
    i=0;
    while (1) {
        sleep_ms(1000);
        Log("in testThread %d:i==%ds\n",n,++i);
        if (i>=5) No_Loop=1;
    }
}
int main(int argc,char * argv[]) {
    int i;
#ifdef _MSC_VER
    InitializeCriticalSection(&cs_log);
#else
    pthread_mutex_init(&cs_log,NULL);
    pthread_t threads[1];
    int threadsN;
    int rc;
#endif
    Log("=========BEGIN==================\n");
#ifdef _MSC_VER
    _beginthread((void(__cdecl *)(void *))testThread,0,(void *)1);
#else
    threadsN=0;
    rc=pthread_create(&(threads[threadsN++]),NULL,testThread,(void *)1);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);
#endif
    i=0;
    while (1) {
        sleep_ms(100);
        Log("in main:i==%d\n",++i);
        if (No_Loop==1) break;//
    }
    Log("=========END====================\n");
#ifdef _MSC_VER
    DeleteCriticalSection(&cs_log);
#else
    pthread_mutex_destroy(&cs_log);
#endif
    return 0;
}
//2012-06-14 16:27:21.500 =========BEGIN==================
//2012-06-14 16:27:21.609 in main:i==1
//2012-06-14 16:27:21.718 in main:i==2
//2012-06-14 16:27:21.828 in main:i==3
//2012-06-14 16:27:21.937 in main:i==4
//2012-06-14 16:27:22.046 in main:i==5
//2012-06-14 16:27:22.156 in main:i==6
//2012-06-14 16:27:22.265 in main:i==7
//2012-06-14 16:27:22.375 in main:i==8
//2012-06-14 16:27:22.484 in main:i==9
//2012-06-14 16:27:22.500 in testThread 1:i==1s
//2012-06-14 16:27:22.593 in main:i==10
//2012-06-14 16:27:22.703 in main:i==11
//2012-06-14 16:27:22.812 in main:i==12
//2012-06-14 16:27:22.921 in main:i==13
//2012-06-14 16:27:23.031 in main:i==14
//2012-06-14 16:27:23.140 in main:i==15
//2012-06-14 16:27:23.250 in main:i==16
//2012-06-14 16:27:23.359 in main:i==17
//2012-06-14 16:27:23.468 in main:i==18
//2012-06-14 16:27:23.500 in testThread 1:i==2s
//2012-06-14 16:27:23.578 in main:i==19
//2012-06-14 16:27:23.687 in main:i==20
//2012-06-14 16:27:23.796 in main:i==21
//2012-06-14 16:27:23.906 in main:i==22
//2012-06-14 16:27:24.015 in main:i==23
//2012-06-14 16:27:24.125 in main:i==24
//2012-06-14 16:27:24.234 in main:i==25
//2012-06-14 16:27:24.343 in main:i==26
//2012-06-14 16:27:24.453 in main:i==27
//2012-06-14 16:27:24.500 in testThread 1:i==3s
//2012-06-14 16:27:24.562 in main:i==28
//2012-06-14 16:27:24.671 in main:i==29
//2012-06-14 16:27:24.781 in main:i==30
//2012-06-14 16:27:24.890 in main:i==31
//2012-06-14 16:27:25.000 in main:i==32
//2012-06-14 16:27:25.109 in main:i==33
//2012-06-14 16:27:25.218 in main:i==34
//2012-06-14 16:27:25.328 in main:i==35
//2012-06-14 16:27:25.437 in main:i==36
//2012-06-14 16:27:25.500 in testThread 1:i==4s
//2012-06-14 16:27:25.546 in main:i==37
//2012-06-14 16:27:25.656 in main:i==38
//2012-06-14 16:27:25.765 in main:i==39
//2012-06-14 16:27:25.875 in main:i==40
//2012-06-14 16:27:25.984 in main:i==41
//2012-06-14 16:27:26.093 in main:i==42
//2012-06-14 16:27:26.203 in main:i==43
//2012-06-14 16:27:26.312 in main:i==44
//2012-06-14 16:27:26.421 in main:i==45
//2012-06-14 16:27:26.500 in testThread 1:i==5s
//2012-06-14 16:27:26.531 in main:i==46
//2012-06-14 16:27:26.531 =========END====================
赵4老师 2021-05-27
  • 打赏
  • 举报
回复
Using Event Objects
Win32-based applications use event objects in a number of situations to notify a waiting thread of the occurrence of an event. For example, overlapped I/O operations on files, named pipes, and communications devices use an event object to signal their completion. For more information about the use of event objects in overlapped I/O operations, see Synchronization and Overlapped Input and Output.

In the following example, an application uses event objects to prevent several threads from reading from a shared memory buffer while a master thread is writing to that buffer. First, the master thread uses the CreateEvent function to create a manual-reset event object. The master thread sets the event object to nonsignaled when it is writing to the buffer and then resets the object to signaled when it has finished writing. Then it creates several reader threads and an auto-reset event object for each thread. Each reader thread sets its event object to signaled when it is not reading from the buffer. 

#define NUMTHREADS 4 

HANDLE hGlobalWriteEvent; 

void CreateEventsAndThreads(void) 
{
    HANDLE hReadEvents[NUMTHREADS], hThread; 
    DWORD i, IDThread; 

    // Create a manual-reset event object. The master thread sets 
    // this to nonsignaled when it writes to the shared buffer. 

    hGlobalWriteEvent = CreateEvent( 
        NULL,         // no security attributes
        TRUE,         // manual-reset event
        TRUE,         // initial state is signaled
        "WriteEvent"  // object name
        ); 

    if (hGlobalWriteEvent == NULL) { 
        // error exit
    }

    // Create multiple threads and an auto-reset event object 
    // for each thread. Each thread sets its event object to 
    // signaled when it is not reading from the shared buffer. 

    for(i = 1; i <= NUMTHREADS; i++) 
    {
        // Create the auto-reset event.
        hReadEvents[i] = CreateEvent( 
            NULL,     // no security attributes
            FALSE,    // auto-reset event
            TRUE,     // initial state is signaled
            NULL);    // object not named

        if (hReadEvents[i] == NULL) 
        {
            // Error exit.
        }

        hThread = CreateThread(NULL, 0, 
            (LPTHREAD_START_ROUTINE) ThreadFunction, 
            &hReadEvents[i],  // pass event handle
            0, &IDThread); 
        if (hThread == NULL) 
        {
            // Error exit.
        }
    }
}
 
Before the master thread writes to the shared buffer, it uses the ResetEvent function to set the state of hGlobalWriteEvent (an application-defined global variable) to nonsignaled. This blocks the reader threads from starting a read operation. The master then uses the WaitForMultipleObjects function to wait for all reader threads to finish any current read operations. When WaitForMultipleObjects returns, the master thread can safely write to the buffer. After it has finished, it sets hGlobalWriteEvent and all the reader-thread events to signaled, enabling the reader threads to resume their read operations. 

VOID WriteToBuffer(VOID) 
{
    DWORD dwWaitResult, i; 

    // Reset hGlobalWriteEvent to nonsignaled, to block readers.
 
    if (! ResetEvent(hGlobalWriteEvent) ) 
    { 
        // Error exit.
    } 

    // Wait for all reading threads to finish reading.

    dwWaitResult = WaitForMultipleObjects( 
        NUMTHREADS,   // number of handles in array
        hReadEvents,  // array of read-event handles
        TRUE,         // wait until all are signaled
        INFINITE);    // indefinite wait

    switch (dwWaitResult) 
    {
        // All read-event objects were signaled.
        case WAIT_OBJECT_0: 
            // Write to the shared buffer.
            break;

        // An error occurred.
        default: 
            printf("Wait error: %d\n", GetLastError()); 
            ExitProcess(0); 
    } 

    // Set hGlobalWriteEvent to signaled.

    if (! SetEvent(hGlobalWriteEvent) ) 
    {
        // Error exit.
    }

    // Set all read events to signaled.
    for(i = 1; i <= NUMTHREADS; i++) 
        if (! SetEvent(hReadEvents[i]) ) { 
            // Error exit.
        } 
}
 
Before starting a read operation, each reader thread uses WaitForMultipleObjects to wait for the application-defined global variable hGlobalWriteEvent and its own read event to be signaled. When WaitForMultipleObjects returns, the reader thread's auto-reset event has been reset to nonsignaled. This blocks the master thread from writing to the buffer until the reader thread uses the SetEvent function to set the event's state back to signaled. 

VOID ThreadFunction(LPVOID lpParam) 
{
    DWORD dwWaitResult, i;
    HANDLE hEvents[2]; 

    hEvents[0] = (HANDLE) *lpParam;  // thread's read event
    hEvents[1] = hGlobalWriteEvent; 

    dwWaitResult = WaitForMultipleObjects( 
        2,            // number of handles in array
        hEvents,      // array of event handles
        TRUE,         // wait till all are signaled
        INFINITE);    // indefinite wait

    switch (dwWaitResult) 
    {

        // Both event objects were signaled.
        case WAIT_OBJECT_0: 
            // Read from the shared buffer.
            break; 

        // An error occurred.
        default: 
            printf("Wait error: %d\n", GetLastError()); 
            ExitThread(0); 
    }

    // Set the read event to signaled.

    if (! SetEvent(hEvents[0]) ) 
    { 
        // Error exit.
    } 
}

赵4老师 2021-05-27
  • 打赏
  • 举报
回复
卡死没准是因为ZT8348_OpenIRQ里面没调用SetEvent(g_hEventSFIFO);
顾染尘 2021-05-27
  • 打赏
  • 举报
回复
引用 4 楼 赵4老师 的回复:
看其中带“★”的行:

ULONG _stdcall ThreadFunc1( LPVOID lpParam ) {
    AfxMessageBox(_T("ThreadFunc1"));
    static int nCount; //产生事件的次数
    while(g_keepRunning)
    {
        //只要事件列表中有一个事件有信号,就结束等待
        ULONG RetForWait = 0xffffffff;
        RetForWait = WaitForSingleObject(g_hEventSFIFO,INFINITE);
        if( RetForWait == WAIT_OBJECT_0 )
        {
            CString tempStr;
            CSFDJController1Dlg* curDlg;
            curDlg = (CSFDJController1Dlg*)AfxGetApp()->m_pMainWnd;
            //显示进入事件的次数
            nCount++;
            tempStr.Format(_T("事件次数: %d"), nCount);
        //  curDlg->SetDlgItemText( IDC_LBL_COUNT, tempStr );
            long retCount; //,i;
            //还是要判断一下才能读,因为此时真正的数据个数可能不到需要的数
            tempStr.Format(_T("SFIFO中数据个数: %d"), ZT8348_GetSFifoDataCount(g_cardNO,1));
            //curDlg->SetDlgItemText( IDC_LBL_DATA_COUNT, tempStr );
            //ZT8348_GetSFifoDataCount得到驱动缓冲区(SFIFO)中当前有效数据的个数
            if( ZT8348_GetSFifoDataCount(g_cardNO,1) >= g_wantCount )
            {
                //ZT8348_AISFifo定时启动AD或外触发启动AD时,从驱动缓冲区(SFIFO)中读一批数 g_wantCount希望得到的个数
                retCount = ZT8348_AISFifo(g_cardNO, 0, g_resultArr, g_wantCount);//g_resultArr采集结果
                //显示前8个数
                 //g_resultArr[i] = 1000.0;
                //每次求平均值个数为30000个,每次间隔100个值
                ZT8348_AISFifoChAver(g_cardNO, 0,g_resultArr,30000,100);

                //ZT8348_AISFifoChAver函数只支持单通道 ,目前状态是1通道值为0,使用2通道,求平均值的时候就需要乘以两倍

                float gaiv = (g_resultArr[1]*2)/(float)1000;//转换单位 将mv转换为v
                float gaimv = (g_resultArr[1]*2);
                tempStr.Format(_T("%7.3f v"), gaimv);//总共七位 其中两位小数点
                curDlg->SetDlgItemText(IDC_LBL_AD1+0, tempStr);

                float kg = 38.18*gaiv;//36.28五个点位求出的平均值
                tempStr.Format(_T("%7.2f KG"), kg);//总共七位 其中两位小数点

                curDlg->SetDlgItemText(IDC_LBL_AD0+0, tempStr);

                PYali=g_resultArr[1];
                /*如果 压力值减去标准值是区间范围*/
                float ca = PYali-chazhi;
                if(ca<=2){
                //  AfxMessageBox(_T("获取稳定压力值的次数 "));
                    countaaa++;
                }
                if(countaaa>3){
                //  PYalir=PYali;
                    PYalia(kg);
                }
                chazhi=PYali;

            }
        }
    }
    return 0;
}


float  StartCaijiwd(){
    cunya=0;
//  AfxMessageBox(_T("开始采集无参数"));
    //新建文件
    if( (g_fp=(fopen("wending.dat","wb")))==NULL)
    {
        AfxMessageBox(_T("open file failed"));
        return -1;
    }
//  AfxMessageBox("PYali");
    //建立一个线程监视事件
    DWORD dwThreadId;
    HANDLE hThread;

    g_hEventSFIFO = CreateEvent(NULL,false,false,NULL);//★zhao4zhong1 因为ThreadFunc1中使用了g_hEventSFIF,所以这句应挪到CreateThread之前
    if( (HANDLE)g_hEventSFIFO == NULL ) {
        AfxMessageBox(_T("CreateEvent failed\n"));
        return -1;
    }

    g_keepRunning = 1;
    hThread = CreateThread(NULL,0,ThreadFunc1,NULL,0,&dwThreadId);
    if (hThread == NULL)
    {
      AfxMessageBox(_T("CreateThread failed\n"));
    }
    else
    {
      CloseHandle( hThread );
    }

    //启动AD
    ZT8348_DisableAD(g_cardNO); //停止定时AD
    ZT8348_ClearHFifo(g_cardNO, 1); //清空硬件FIFO(HFIFO)
    ZT8348_ClearSFifo(g_cardNO, 1); //清空软件FIFO(SFIFO)
    if( ZT8348_GetSFifoSize(g_cardNO, 1) != 2000 )
    {
        if( ZT8348_SetSFifoSize(g_cardNO, 1, 2000) != 2000 )
        {
            CString tempStr1;
            tempStr1.Format(_T("g_cardNO: %d"), g_cardNO);
            AfxMessageBox(tempStr1);
            AfxMessageBox(_T("未申请到足够的缓冲区"));
            CString tempStr;
            tempStr.Format(_T("错误号: %d"), ZT8348_GetLastErr());
            AfxMessageBox(tempStr);

            return -1;
        }
    }

    g_wantCount = 1024000;//200000;
    ZT8348_SetSFifoThreshold(g_cardNO, 1, g_wantCount); //设置SFIFO阀值
    //打开中断,注意HFIFO超过半满时打开中断会死机
    //建立一个事件
//  g_hEventSFIFO = CreateEvent(NULL,false,false,NULL);//★zhao4zhong1 因为ThreadFunc1中使用了g_hEventSFIF,所以这句应挪到CreateThread之前
    if( (HANDLE)g_hEventSFIFO != NULL )
        ZT8348_OpenIRQ(g_cardNO, (long)g_hEventSFIFO, 0); //打开中断

    ULONG AIRangeArr[8];
    ULONG ampInxArr[8];
    //不能用,因为并未把所有元素初始化为2,ULONG AIRangeArr[8] = {2};
    //ULONG ampInxArr[8] = {0};
    //公式:采样频率= 16000000Hz/(分频系数+1)
    const ULONG ADinClock = 16000000;
    ULONG ADfreq = 500000;//分频系数
    ULONG ADstartModeWord = 1; //定时启动
    ULONG i;
    //量程为 -10~+10V
    for(i=0; i<8; i++)
    {//2 :  0-- +10000mV
        AIRangeArr[i] = 2;// 6;//按照 -10000 -- +10000mV 量程装入零 点和满度值,必须与板卡的实际跳线相一致
        ampInxArr[i] = 0;
    }

    ZT8348_AIinit(g_cardNO, 0, 2, AIRangeArr, ampInxArr, ADstartModeWord, ADinClock / ADfreq - 1, 0, 0);
    ZT8348_EnableAD(g_cardNO); //启动定时AD

    //返回函数执行的状态
    CString tempStr;
    tempStr.Format(_T("错误号: %d"), ZT8348_GetLastErr());

    /*PYali是在取值区间范围内返回触发停止采集*/
    //AfxMessageBox("2333333");
//  float att = 5000;
//  Sleep(3000);
    while(0.02){
        Sleep(6000);
        if(cunya>0){
        //  AfxMessageBox(_T("成功获取压力值"));
            return cunya;
        }
    //  AfxMessageBox(_T("等待2秒获取稳定压力值"));
    }

//  return 0;
}

void StopCaiji(){
    //停止采集
    fclose(g_fp);//关闭
    ZT8348_CloseIRQ(g_cardNO); //关闭中断
    //返回函数执行的状态
    CString tempStr;
    tempStr.Format(_T("错误号: %d"), ZT8348_GetLastErr());


    g_keepRunning = 0;
    if( (HANDLE)g_hEventSFIFO != NULL )
    {
        if( CloseHandle( g_hEventSFIFO ) != 0L )
        {
            g_hEventSFIFO = NULL;
            AfxMessageBox(_T("关闭采集"));
        }
    }

    return ;
}

星语句移到上面去还是会卡死状态
顾染尘 2021-05-26
  • 打赏
  • 举报
回复
有一个想法,判断ThreadFunc1这个线程是否在运行,运行在执行线程while(a),不知道有没有这个函数可以去做判断,我没有在网上搜到

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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