Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [C++] Вычисление контрольной суммы CRC32, Готовый класс для работы 
V
    Опции темы
MuForum
  Дата 16.5.2011, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: нет
Всего: 4



Доброго времени суток.
Выкладываю готовый класс для вычисления контрольной суммы файла CRC32.
Код

#ifndef TCRC32_H
#define TCRC32_H

#include <windows.h>
#include <stdio.h>

class TCRC32
{
    #define BUFFERSIZE  65536U // 2^16;
    #define CRC_MASK    0xFFFFFFFFUL
    #define CRC_POLY     0xEDB88320UL
    // ----
    private:
        DWORD        m_CRC32Table[256];
        // ----
        char            m_Buf[BUFFERSIZE];
    
    private:
        #define UPDATE_CRC(crc, c) crc = m_CRC32Table[(BYTE)crc ^ (BYTE)(c)] ^ (crc >> 8)
        // ----
        void    Init_CRC32_Table()
        {
            UINT i        = 0;
            UINT j        = 0;
            DWORD r        = 0;
            // ----
            for(i = 0; i < 256; i++)
            {
                r = i;
                // ----
                for (j = 8; j > 0; j--)
                {
                    if ( (r & 1) == 1 ) r = ((r >> 1) ^ CRC_POLY); else r >>= 1;
                }
                // ----
                m_CRC32Table[i]        = r;
            }
        }

    public:
        TCRC32()
        {
            Init_CRC32_Table();
        }
        ~TCRC32() { }
        // ----
        DWORD    CalcSize(const PCHAR szFilePath)
        {
            DWORD dwLength    = 0;
            // ----
            HANDLE hFile    = CreateFile(szFilePath, 0, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
            // ----
            if ( hFile != NULL )
            {
                dwLength = GetFileSize(hFile, 0);
                CloseHandle(hFile);
            }
            // ----
            return dwLength;
        }
        DWORD    CalcCRC32(const PCHAR szFilePath)
        {
            FILE * fp    = fopen(szFilePath, "rb");
            // ----
            if ( fp == NULL )
            {
                return 0;
            }
            // ----
            DWORD dwCRC32        = CRC_MASK;
            // ----
            int i                = 0;
            size_t len            = 0;
            // ----
            while( (len = fread(m_Buf, 1, BUFFERSIZE, fp)) > 0 )
            {
                for(i = 0; len > 0; len--, i++)
                {
                    UPDATE_CRC(dwCRC32, m_Buf[i]);
                }
            }
            // ----
            fclose(fp);
            // ----
            return dwCRC32;
        }
        DWORD    CalcCRC32(const PCHAR szFilePath, const bool & bShouldStop)
        {
            FILE * fp    = fopen(szFilePath, "rb");
            // ----
            if ( fp == NULL )
            {
                return 0;
            }
            // ----
            DWORD dwCRC32        = CRC_MASK;
            // ----
            int i                = 0;
            size_t len            = 0;
            // ----
            while( bShouldStop == false )
            {
                len        = fread(m_Buf, 1, BUFFERSIZE, fp);
                // ----
                if ( len < 1 ) break;
                // ----
                for(i = 0; len > 0; len--, i++)
                {
                    UPDATE_CRC(dwCRC32, m_Buf[i]);
                }
            }
            // ----
            fclose(fp);
            // ----
            return dwCRC32;
        }
};

#endif



P.S. -> Когда-то идею для этого решение нашел где-то в интернете, переделал под свои нужны, а нужды заключались в скорости работы алгоритма и использовании класса под многоядерность.

P.S. -> Если у кого-то есть идеи как ещё оптимизировать работу данного класса, прошу говорить. Буду только рад.
- Данный класс реализован под многоядерность, чтобы каждый поток мог сделать экземплатор класса и использовать его.

Это сообщение отредактировал(а) MuForum - 16.5.2011, 13:22


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
volatile
Дата 17.5.2011, 00:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 13
Всего: 85



Цитата(MuForum @  16.5.2011,  13:02 Найти цитируемый пост)
как ещё оптимизировать работу данного класса

Честно говоря, код сильно не смотрел. Но бросилось в глаза самое грубое.

Цитата(MuForum @  16.5.2011,  13:02 Найти цитируемый пост)
    private:
        DWORD        m_CRC32Table[256];
Зачем в каждом экземпляре этот массив?
Его нужно сделать статическим, в расшаренной памяти. Фактически это константы.

Ну и как следствие:
Цитата(MuForum @  16.5.2011,  13:02 Найти цитируемый пост)
    public:
        TCRC32()
        {
            Init_CRC32_Table();
        }
Зачем его инициализировать в каждом экземпляре?
Достаточно один раз, проинициализировать, когда запускается первый экз.

Вот немножко сократили использование память (1024 байта на каждый экземпляр)
И ускорили работу smile

можно капнуть и глубже, но пока и этого я думаю хватит.
PM MAIL   Вверх
borisbn
Дата 17.5.2011, 08:57 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 6
Всего: 135



Щаз буду критиковать smile
1. Почему в разделе WinAPI ?
2. Почему ф-ция CalcSize не статическая ? И зачем вообще она нужна в классе, вычисляющем CRC ?
3. Класс завязан на чтение из файла. Лучше сделать его так, чтобы он работал с памятью, т.к. сегодня это файл, завтра - сеть... да мало ли ещё что
4. Почему бы из первой ф-ции CalcCRC32 не вызвать вторую со вторым параметром false ? Повторное использование кода - оно завсегда лучше
5. Зачем мешать winAPI и Си++ CRT (CreateFile и fopen) ? Вычислить длину файла можно и ф-циями CRT:
Код

FILE * f = fopen...
unsigned long fileSize = _filelength( _fileno( f ) );

6. Константы  BUFFERSIZE, CRC_MASK и CRC_POLY лучше сделать не define'ами, а static const unsigned int, чтобы при включении твоего h-ника не возникало перекрытия с другими переменными.
7. Почему переменная i типа int, а len - size_t ? Лучше сделать одинаково.
8. (возможно уже придирка, но...) Зачем нужна привязка к Windows (#include <windows.h>) ? Если из-за CreateFile, то см. п. 5, если из-за DWORD, то лучше пользоваться встроенными, а не M$-совскими типами.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
MuForum
Дата 17.5.2011, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: нет
Всего: 4



# Вариант №2: (Класс под ОС Windows)
Код

#ifndef TCRC32_H
#define TCRC32_H

#include <windows.h>
#include <stdio.h>

class TCRC32
{
private:
    DWORD    m_CRC32Table[256];

private:
    void inline    UPDATE_CRC(DWORD & crc, BYTE c) { crc = m_CRC32Table[(BYTE)crc ^ c] ^ (crc >> 8); }
    // ----
    void    Init_CRC32_Table()
    {
        UINT i = 0, j = 0;
        DWORD r        = 0;
        DWORD dwCRC_POLY    = 0xEDB88320UL;
        // ----
        for(i = 0; i < 256; i++)
        {
            r = i;
            // ----
            for (j = 8; j > 0; j--)
            {
                if ( (r & 1) == 1 ) r = ((r >> 1) ^ dwCRC_POLY); else r >>= 1;
            }
            // ----
            m_CRC32Table[i]        = r;
        }
    }
public:
    TCRC32()
    {
        Init_CRC32_Table();
    }
    ~TCRC32() { }
    // ----
    DWORD    GetSize(const PCHAR szFilePath)
    {
        DWORD dwLength    = 0;
        // ----
        HANDLE hHandle    = CreateFile(szFilePath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
        // ----
        if ( hHandle != INVALID_HANDLE_VALUE )
        {
            SetFilePointer(hHandle, 0, NULL, FILE_BEGIN);
            dwLength    = GetFileSize(hHandle, 0);
            CloseHandle(hHandle);
        }
        // ----
        return dwLength;
    }
    // ----
    DWORD    GetCRC32(const PCHAR szFilePath, const bool & bShouldStop = false)
    {
        HANDLE hHandle    = CreateFile(szFilePath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
        // ----
        if ( hHandle == INVALID_HANDLE_VALUE ) return 0;
        // ----
        SetFilePointer(hHandle, 0, NULL, FILE_BEGIN);
        // ----
        DWORD dwCRC32        = 0xFFFFFFFFUL; // CRC_MASK;
        // ----
        int iRes;
        DWORD i, dwReadedBytes;
        char m_Buf[65536U];
        // ----
        while( bShouldStop == false )
        {
            iRes    = ReadFile(hHandle, m_Buf, 65536U, & dwReadedBytes, NULL);
            // ----
            if ( (iRes == 0) || (dwReadedBytes < 1) ) break;
            // ----
            for(i = 0; dwReadedBytes > 0; dwReadedBytes--, i++) UPDATE_CRC(dwCRC32, m_Buf[i]);
        }
        // ----
        CloseHandle(hHandle);
        // ----
        return dwCRC32;
    }
    // ----
    DWORD    GetCRC32(const PCHAR szInBuf, DWORD dwLength, const bool & bShouldStop = false)
    {
        DWORD dwCRC32        = 0xFFFFFFFFUL; // CRC_MASK;
        // ----
        for(DWORD i = 0; (i < dwLength) && (bShouldStop == false); i++)
        {
            UPDATE_CRC(dwCRC32, szInBuf[i]);
        }
        // ----
        return dwCRC32;
    }
};

#endif



Это сообщение отредактировал(а) MuForum - 17.5.2011, 15:04


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
borisbn
Дата 17.5.2011, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 6
Всего: 135



MuForum, у тебя опять повторяется код:
Цитата(MuForum @  17.5.2011,  15:03 Найти цитируемый пост)
 for(i = 0; dwReadedBytes > 0; dwReadedBytes--, i++) UPDATE_CRC(dwCRC32, m_Buf[i]);

и
Цитата(MuForum @  17.5.2011,  15:03 Найти цитируемый пост)

for(DWORD i = 0; (i < dwLength) && (bShouldStop == false); i++)
{
    UPDATE_CRC(dwCRC32, szInBuf[i]);
}

и потом, я говорил не избавиться от define'ов, а переделать их в static const unsigned int...
ok, лови
Код

#ifndef TCRC32_H
#define TCRC32_H

//#include <windows.h> // завязка на windows IMHO не нужна. пусть код будет кроссплатформенный
#include <stdio.h>
#include <io.h>

class TCRC32
{
public: // public секции лучше ставить в начале, чтобы тому, кто будет юзать твой класс были сразу видны нужные ему ф-ции
    TCRC32()
    {
        Init_CRC32_Table();
    }
    ~TCRC32() { }
    // ----
    // Всё равно не понимаю - зачем эта ф-ция в классе, вычисляющем CRC ???
    static unsigned int GetSize( const char * szFilePath )
    {
        unsigned long dwLength = 0;
        FILE * f = fopen( szFilePath, "r" );
        if ( f )
        {
            dwLength = filelength( fileno( f ) );
            fclose( f );
        }
        return dwLength;
    }
    // ----
    unsigned long GetCRC32File( const char * szFilePath, const bool & bShouldStop = false )
    {
        FILE * file = fopen( szFilePath, "rb" );
        if ( file == 0 )
        {
            return 0;
        }
        unsigned long dwCRC32 = CRC_MASK;
        while( bShouldStop == false )
        {
            unsigned long dwReadedBytes = fread( m_Buf, 1, BUFF_SIZE, file );
            if ( dwReadedBytes < 1 )
            {
                break;
            }
            dwCRC32 = GetCRC32( m_Buf, dwReadedBytes, dwCRC32, bShouldStop );
        }
        fclose( file );
        return dwCRC32;
    }
    // ----
    unsigned long GetCRC32( const char * buf, unsigned long dwLength, const unsigned long & initCRC32 = CRC_MASK, const bool & bShouldStop = false )
    {
        unsigned long dwCRC32 = initCRC32;
        // ----
        for ( unsigned long i = 0; ( i < dwLength ) && ( bShouldStop == false ); i++ )
        {
            UPDATE_CRC( dwCRC32, buf[ i ] );
        }
        // ----
        return dwCRC32;
    }


private:
    static const unsigned long CRC_MASK = 0xFFFFFFFFU; 
    static const unsigned long dwCRC_POLY = 0xEDB88320U;
    static const unsigned long BUFF_SIZE = 65536U; 
    unsigned long m_CRC32Table[ 256 ];
    char m_Buf[ BUFF_SIZE ];

private:
    inline void UPDATE_CRC( unsigned long & crc, unsigned char c )
    {
        crc = m_CRC32Table[(unsigned char)crc ^ c] ^ (crc >> 8);
    }
    // ----
    void Init_CRC32_Table()
    {
        unsigned int i = 0, j = 0;
        unsigned long r = 0;
        // ----
        for(i = 0; i < 256; i++)
        {
            r = i;
            // ----
            for (j = 8; j > 0; j--)
            {
                if ( (r & 1) == 1 )
                    r = ((r >> 1) ^ dwCRC_POLY);
                else
                    r >>= 1;
            }
            // ----
            m_CRC32Table[i]        = r;
        }
    }
};

#endif


Это сообщение отредактировал(а) borisbn - 17.5.2011, 16:05


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
volatile
Дата 17.5.2011, 23:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 13
Всего: 85



Цитата(borisbn @  17.5.2011,  16:02 Найти цитируемый пост)
    void Init_CRC32_Table()
    {
        unsigned int i = 0, j = 0;
        unsigned long r = 0;
        // ----
        for(i = 0; i < 256; i++)
        {
            r = i;
            // ----
            for (j = 8; j > 0; j--)
            {
                if ( (r & 1) == 1 )
                    r = ((r >> 1) ^ dwCRC_POLY);
                else
                    r >>= 1;
            }
            // ----
            m_CRC32Table[i]        = r;
        }
    }

Этот цикл вызывается каждый раз при создании экземпляра.
Не нужно, я уже писал вначале, ззачем такой оверхед?

либо
Код

void Init_CRC32_Table()
{
    static bool inited = 0;
    if (inited) return;
    // здесь цикл
    inited = 1;
}

либо, что лучше, вобще задать константами.
можно хелпер небольшой написать для этого.

Добавлено через 10 минут и 14 секунд
Ну вот сделал из вашего кода небольшой хелпер.
http://liveworkspace.org/code/325ff767078a...109f7799f1ba649
В данном исключительном случае, код надо копировать не из верхней части, а из нижней! smile 
Куда его копировать, надеюсь понятно.
Init_CRC32_Table() вобще удалить нафиг, и конструктор походу можно удалить.

PM MAIL   Вверх
borisbn
Дата 18.5.2011, 00:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 6
Всего: 135



volatile, скажу по секрету (никому не говорите), я этот классик себе взял (чего добру пропадать) и сделал как Вы говорили, но чуток по другому
Код

int CRC32::Init_CRC32_Table() { // именно int !
...
}

int dummy = CRC32::Init_CRC32_Table(); // один статический вызов

в Вашем же варианте
Цитата

void Init_CRC32_Table()
{
    static bool inited = 0;
    if (inited) return;
    // здесь цикл
// а вдруг много потоков параллельно создают экземпляры этого класса...
    inited = 1;
}

при многопоточности код заполнения массива может вызваться несколько раз. В данном случае - ничего страшного (кода-то кодт наплакал), а если там серьёзные операции...

Мне понравилась идея в C# - там есть статический конструктор не для экземпляров, а для типа. Его достаточно просто описать и он вызовется гарантированно один раз.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
volatile
Дата 18.5.2011, 01:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 13
Всего: 85



Цитата(borisbn @  18.5.2011,  00:31 Найти цитируемый пост)
а вдруг много потоков параллельно создают экземпляры этого класса...

Ну это да, хотя ничего страшного не будет в данном случае. они же пишут одно и тоже smile 
небольшой оверхед в начале. Ну и поэтому я затем привел вариант с константами.
Самый надежный и быстрый по-любому.

Цитата(borisbn @  18.5.2011,  00:31 Найти цитируемый пост)
int dummy = CRC32::Init_CRC32_Table(); // один статический вызов

С этим кода тоже не все шоколадно.
например, вы написали int dummy = ...; в одном файле.
а в другом файле объявлена глобальная переменная
TCRC32 a;

какой код будет выполнен первый? это неопределено. 50% можно нарваться на большие неприятности.
здесь, если по-хорошему надо делать синглтон.
Но мне его лень щас было писать.
Проще быстрее и надежнее с константами, что и было сделано. Чем не нравиться?

PM MAIL   Вверх
borisbn
Дата 18.5.2011, 01:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 6
Всего: 135



Цитата(volatile @  18.5.2011,  01:22 Найти цитируемый пост)
а в другом файле объявлена глобальная переменная TCRC32 a;

так она ж просто объявлена. таблицу ещё никто не юзает... хотя в общем случае - да. так тоже нехорошо.

Цитата(volatile @  18.5.2011,  01:22 Найти цитируемый пост)
здесь, если по-хорошему надо делать синглтон.

те же проблемы с многопоточностью. и потом, синглтоны - зло (щаз на меня набросятся)


Цитата(volatile @  18.5.2011,  01:22 Найти цитируемый пост)
Чем не нравиться?

мягким знаком  smile 

да нет... нравится. только неплохо бы вставить в комментарии код генерации этих констант, чтобы через год, открыв код, можно было не ломать голову, откуда они (константы) взялись.

По-моему, мы воду в ступе толчём. IMHO и так всё понятно. Нет ?


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
volatile
Дата 18.5.2011, 02:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 13
Всего: 85



Цитата(borisbn @  18.5.2011,  01:37 Найти цитируемый пост)
мягким знаком   

да..., извиняюсь. Моя учительница по русскому до сих пор плачет.

Цитата(borisbn @  18.5.2011,  01:37 Найти цитируемый пост)
IMHO и так всё понятно. Нет ? 

 smile 
PM MAIL   Вверх
GremlinProg
Дата 18.5.2011, 06:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(borisbn @  18.5.2011,  02:31 Найти цитируемый пост)

void Init_CRC32_Table(){
    static LONG inited = 0;
    if ( _InterlockedExchange( &inited, 1 ) ) return;
    // здесь цикл
// а вдруг много потоков параллельно создают экземпляры этого класса...
    inited = 1;
}

это если без хелпера, вместо синглтона, тогда да, действительно, "а вдруг ..."

Добавлено через 5 минут и 7 секунд
в таком случае, конечно m_CRC32Table - тоже статик


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
borisbn
Дата 18.5.2011, 08:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 6
Всего: 135



GremlinProg, оооочень не хочется класс вычисления CRC завязывать на Windows. Можно, конечно, написать свою ф-цию interlock с ifdef'ами внутри... но, как-то это не кошерно smile


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
GremlinProg
Дата 18.5.2011, 11:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(borisbn @  18.5.2011,  10:31 Найти цитируемый пост)
Можно, конечно, написать свою ф-цию interlock с ifdef'ами внутри... но, как-то это не кошерно

ну, префикс lock не распространяется на Windows, это архитектурная фича,
а _InterlockedExchange - не функция, по большому счету (см. intrinsic),

но если уж и заниматься оптимизацией, значит быть готовым и к таким "ifdef'ам",

возможно, тут стоит задействовать, к примеру, ключ
Код

#define MULTITHREADING

и руководстоваться им в более узком направлении оптимизации

Добавлено через 8 минут и 16 секунд
ps: сам бы я не стал возиться с таким конструктором, это был просто вариант, чтобы учесть MT малой кровью


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
volatile
Дата 18.5.2011, 23:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 13
Всего: 85



Цитата(GremlinProg @  18.5.2011,  06:27 Найти цитируемый пост)
void Init_CRC32_Table(){
    static LONG inited = 0;
    if ( _InterlockedExchange( &inited, 1 ) ) return;
    // здесь цикл
}

А вот так делать НЕЛЬЗЯ!!!
Давайте рассуждать...
Первый поток вызывает _InterlockedExchange( &inited, 1 ) 
Получает 0, начинает инициализировать массив, заметьте только начинает, еще не проинициализировал.
В это время второй поток вызывает _InterlockedExchange( &inited, 1 ) 
Получает единицу, дескать все ОК, массив готов, возвращается, начинает считать CRC.
Но массива у нас пока НЕТ! smile 

PM MAIL   Вверх
borisbn
Дата 19.5.2011, 00:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 6
Всего: 135



Цитата(volatile @  18.5.2011,  23:33 Найти цитируемый пост)
А вот так делать НЕЛЬЗЯ!!!

хмммм. а как же быть ? Я не про класс CRC - мы уже родили 2 варианта:
1. 
Цитата(borisbn @  18.5.2011,  00:31 Найти цитируемый пост)
int dummy = CRC32::Init_CRC32_Table(); // один статический вызов

2. 
Цитата(volatile @  17.5.2011,  23:41 Найти цитируемый пост)
Ну вот сделал из вашего кода небольшой хелпер.

Допустим мой тип (не экземпляр) должен инициализировать свой статический массив данными из файла... Чо делать ?

Эххххх. Вполне возможно придётся на старости лет поизучать что-нибудь другое - До-диез, например... Всё-таки молодой, бурно развивающийся язык/framework...
Для данной задачи даже есть готовое решение на уровне конструкции/синтаксиса языка:
Цитата(borisbn @  18.5.2011,  00:31 Найти цитируемый пост)
Мне понравилась идея в C# - там есть статический конструктор не для экземпляров, а для типа. Его достаточно просто описать и он вызовется гарантированно один раз.




--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1036 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.