线程在WIC

时间:2015-06-02 01:16:05

标签: c multithreading wic

我使用WIC制作了一个编码器。然后我试图使用线程最耗时的部分。

/*Encodes a bitmap source*/
hr = piBitmapFrame->WriteSource(
    piBitmapSrc,    /*bitmap source*/
    rc              /*area which need to be wrote*/
    );

piBitmapSrc→WICBitmap

rc→WICRect,矩形区域来做工作

这就是我试过的方式。

HRESULT writeSrc(
    IWICBitmapFrameEncode *piBitmapFrame,
    IWICBitmap *piBitmapSrc,
    WICRect *rc
    )
{
    /*Encodes a bitmap source*/
    hr = piBitmapFrame->WriteSource(
        piBitmapSrc,    /*bitmap source*/
        rc              /*area which need to be wrote*/
        );

    return hr;
}

然后我称之为

const int numberOfThreads = 4;
std::thread t[numberOfThreads];
int ht = (lHeight / numberOfThreads);

WICRect rc;
rc.X = 0;
rc.Height = ht;
rc.Width = lWidth;

rc.Y = 0;
t[0] = std::thread(writeSrc, piBitmapFrame, piBitmapSrc, &rc);     

rc.Y += ht;
t[1] = std::thread(writeSrc, piBitmapFrame, piBitmapSrc, &rc);

rc.Y += ht;
t[2] = std::thread(writeSrc, piBitmapFrame, piBitmapSrc, &rc);

rc.Y += ht;
rc.Height = (lHeight - (3*ht));
t[3] = std::thread(writeSrc, piBitmapFrame, piBitmapSrc, &rc);

t[0].join();
t[1].join();
t[2].join();
t[3].join();

问题是,piBitmapFrame->WriteSource()被调用了4次,但只有1次返回S_OK。其他3个返回错误代码

  

WINCODEC_ERR_STREAMWRITE

  

WINCODEC_ERR_CODECTOOMANYSCANLINES

为什么会这样。我怎么能正确地使用线程来做到这一点

1 个答案:

答案 0 :(得分:2)

您可能希望更多地研究线程。线程共享全局数据和资源。在您的示例中,您将在所有四个线程中共享piBitMapFrame和WICRect结构。

考虑到WICRect结构,您在调度线程时实际上正在修改数据。一旦修改,该数据将对所有运行的线程可见。所有线程都引用了您声明的单个WICRect,如果它们检查相同的变量两次 - 它们可能会发现它不同。

我不熟悉这个库,但你应该检查WriteSource是否是一个线程安全的调用。 piBitmapFrame是否包含可能通过调用WriteSource修改的数据?回想上面的WICRect示例,WriteSource可能无法处理内部数据在呼叫中途的变化。

示例:

这个程序试图在两个执行线程中打印到stdout,而没有任何同步关于谁在写什么时候。这不会崩溃,cout是线程安全的,但它不会产生你可能期望的输出。输出将是stdout缓冲区中的两个线程交错字符。

#include <iostream>
#include <thread>

void say_hello(){

    /* no locking to prevent stdout contention */
    for ( int i = 0; i < 10; i++){
        std::cout << "Hello from thread " << std::this_thread::get_id() << "!!!" << std::endl;
    }
}

int main(){

    int i;
    // create our thread 
    std::thread ct1(say_hello);

    // say hello ourselves 
    say_hello();

    // wait for thread ct1 to finish execution.
    ct1.join();
    return i;
}

示例输出:

HHeelllloo  ffrroomm  tthhrreeaadd  00xx170fcf5fd78b000007!3!0!0
!!H!e
llHoe lflroo mf rtohmr etahdr e0axd1 00cx57df8f0f070b!0!0!7
30H0e!l!l!o
 fHreolml ot hfrreoamd  t0hxr1e0acd5 d08x070f0f!f!7!b
00H7e3l0l0o! !f!r
omH etlhlroe afdr o0mx 1t0hcr5eda8d0 000x!7!f!f
f7Hbe0l0l7o3 0f0r!o!m! 
thHreelaldo  0fxr1o0mc 5tdh8r0e0a0d! !0!x
7fHfefl7lbo0 0f7r3o0m0 !t!h!r
eaHde l0lxo1 0fcr5odm8 0t0h0r!e!a!d
 0Hxe7lflfof 7fbr0o0m7 3t0h0r!e!a!d
 0Hxe1l0lco5 df8r0o0m0 !t!h!r
eaHde l0lxo7 fffrfo7mb 0t0h7r3e0a0d! !0!x
10Hce5ldl8o0 0f0r!o!m! 
thHreelaldo  0fxr7ofmf ft7hbr0e0a7d3 000x!1!0!c
5dH8e0l0l0o! !f!r
omH etlhlroe afdr o0mx 7tfhfrfe7abd0 007x31000c!5!d!8
00H0e!l!l!o
 from thread 0x7fff7b007300!!!