0xC0000005多线程动画错误

时间:2018-03-20 09:11:36

标签: c++ multithreading animation console-application borland-c++

所以我使用C ++ Console创建了一个应用程序,如下所示,我有一个错误0x0000005。

第一次运行时它照常运行。任何人都可以帮我解决这个问题吗?

我在Borland C ++ 5.5中使用Code :: Blocks IDE,我打算将其转换为Borland C ++ 5.02

#include <windows.h>
#include <stdio.h>
#include <dos.h>
#include <iostream.h>
#include <conio.h>

void linesmov(int mseconds, int y);

void linesmov(int mseconds, int y)
{
    int i=0;
    while (true)
    {
        i=i+1;
        // Or system("cls"); If you may...
        gotoxy(i,y);   
        cout << "____||____||____"; 
        gotoxy(i-1,y);
        cout << " ";
        Sleep(mseconds);
        if (i>115)
        {     
            i=0;  
            for(int o = 0; o < 100; o++)
            {
                gotoxy(0,y);   
                cout << "                  ";
            }
        }
    }
}

DWORD WINAPI mythread1(LPVOID lpParameter)
{
    printf("Thread inside %d \n", GetCurrentThreadId());
    linesmov(5,10);
    return 0;
}
DWORD WINAPI mythread2(LPVOID lpParameter)
{
    printf("Thread inside %d \n", GetCurrentThreadId());
    linesmov(30,15);
    return 0;
}

int main(int argc, char* argv[])
{
    HANDLE myhandle1;
    DWORD mythreadid1;
    HANDLE myhandle2;
    DWORD mythreadid2;
    myhandle1 = CreateThread(0,0,mythread1,0,0,&mythreadid1);
    myhandle2 = CreateThread(0,0,mythread2,0,0,&mythreadid2);
    printf("Thread after %d \n", mythreadid1);

    getchar();
    return 0;
}

2 个答案:

答案 0 :(得分:1)

包括我在内的评论中的所有这些解决方案绝对不是应该如何完成的。主要问题是线程之间缺乏同步以及缺少处理它们的终止。此外,应检查每个函数的线程安全兼容性,或者应将其包装以匹配它。

从c ++ 11开始考虑std::cout我们有一些数据争用保证:

  

同步访问同步(§27.5.3.4)标准iostream   对象的格式化和未格式化输入(第27.7.2.1节)和输出   (§27.7.3.1)函数或多个线程的标准C流应   不会导致数据竞争(§1.10)。 [注意:用户仍必须   通过多个同步这些对象和流的并发使用   线程,如果他们希望避免交错字符。 - 结束说明]

根据本说明,所以同步原语的存在是遗忘的。

考虑处理线程终止。

HANDLE threadH = CreateThread(...);
...
TerminateThread(threadH, 0); // Terminates a thread.
WaitForSingleObject(threadH, INFINITE); // Waits until the specified object is in the signaled state or the time-out interval elapses.
CloseHandle(threadH); // Closes an open object handle.

TerminateThread(),但请注意此解决方案because ..

WaitForSingleObject()

这只是线程安全方式的第一步。

我想推荐C ++ Concurrency in Action:实用多线程作者Anthony Williams进一步阅读。

同步输出的粗鲁解决方案

#include <Windows.h>
#include <iostream>
#include <mutex>

std::mutex _mtx; // global mutex

bool online = true; // or condition_variable

void gotoxy(int x, int y)
{
    COORD c = { x, y };
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
}

void linesmov(int mseconds, int y) {
    int i = 0;
    while (online) {
        i = i + 1;
        // Or system("cls"); If you may...

        _mtx.lock(); // <- sync here
        gotoxy(i, y);
        std::cout << "____||____||____"; gotoxy(i - 1, y);
        std::cout << " ";
        _mtx.unlock();  

        Sleep(mseconds);
        if (i > 75)
        {
            i = 0;
            for (int o = 0; o < 60; o++)
            {
                _mtx.lock(); // <- sync here
                gotoxy(0, y);
                std::cout << "                  ";
                _mtx.unlock();
            }
        }
    }
}

DWORD WINAPI mythread1(LPVOID lpParameter)
{
    std::cout << "Thread 1" << GetCurrentThreadId() << std::endl;
    linesmov(5, 10);
    return 0;
}
DWORD WINAPI mythread2(LPVOID lpParameter)
{
    std::cout << "Thread 2" << GetCurrentThreadId() << std::endl;
    linesmov(30, 15);
    return 0;
}

int main(int argc, char* argv[])
{
    DWORD mythreadid1;
    DWORD mythreadid2;
    HANDLE myhandle1 = CreateThread(0, 0, mythread1, 0, 0, &mythreadid1);
    HANDLE myhandle2 = CreateThread(0, 0, mythread2, 0, 0, &mythreadid2);

    std::cout << "Base thread: " << GetCurrentThreadId() << std::endl;

    getchar();

    online = false;

    WaitForSingleObject(myhandle1, INFINITE);
    WaitForSingleObject(myhandle2, INFINITE);

    CloseHandle(myhandle1);
    CloseHandle(myhandle2);

    return 0;
}

答案 1 :(得分:0)

a)不通过std :: cout输出的gotoxy都不是线程安全/同步的。您需要进程范围的互斥锁才能同步

b)异常可能是因为您没有在main中使用where来等待线程完成。根据硬件和优化,主线程可能会在线程完成其工作之前退出。