Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用C语言实现windowsapi多线程_C_Windows_Multithreading - Fatal编程技术网

用C语言实现windowsapi多线程

用C语言实现windowsapi多线程,c,windows,multithreading,C,Windows,Multithreading,我已经编写了如下代码,它应该以随机顺序打印出0到10的数字 #include <stdio.h> #include <stdlib.h> #include <windows.h> #define THREAD_COUNT 10 DWORD WINAPI t_work(LPVOID param) { printf("%d\n", *((int *) param)); return 0; } int main() {

我已经编写了如下代码,它应该以随机顺序打印出0到10的数字

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

#define THREAD_COUNT 10

DWORD WINAPI t_work(LPVOID param) {
    printf("%d\n", *((int *) param));
    return 0;
}

int main() {

    DWORD *thread_id = malloc(THREAD_COUNT * sizeof(DWORD));
    HANDLE *threads = malloc(THREAD_COUNT * sizeof(HANDLE));
    int *data = malloc(THREAD_COUNT * sizeof(int));
    int i;
    for (i = 0; i < THREAD_COUNT; i++) {
        *(data + i) = i;
        //printf("Debugging value: %d\n", i);
        *(threads + i) = CreateThread(
            NULL,               // default security attributes
            0,                  // use default stack size
            t_work,             // thread function name
            (data + i),         // argument to thread function
            0,                  // use default creation flags
            (thread_id + i));   // returns the thread identifier
    }
    WaitForMultipleObjects(THREAD_COUNT, threads, TRUE, INFINITE);
    int k;
    for (k = 0; k < THREAD_COUNT; k++) {
        CloseHandle(*(threads + k));
    }

    // free memory
    free(thread_id);
    free(data);

    return 0;
}
跑步#2

PS C:\Users\tdw\Work\C Test Project> .\hw.exe
0
6
6
8
8
9
9
4
3
3
编辑1:

我使用的是Visual Studio代码版本1.50.1

以下是编译器的详细信息:

PS C:\Users\tdw\Work\C Test Project> gcc -v
Using built-in specs.
COLLECT_GCC=/usr/bin/gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-cygwin/10/lto-wrapper.exe
Target: x86_64-pc-cygwin
Configured with: /mnt/share/cygpkgs/gcc/gcc.x86_64/src/gcc-10.2.0/configure - 
-srcdir=/mnt/share/cygpkgs/gcc/gcc.x86_64/src/gcc-10.2.0 --prefix=/usr -- 
exec- 
prefix=/usr --localstatedir=/var --sysconfdir=/etc -- 
docdir=/usr/share/doc/gcc 
--htmldir=/usr/share/doc/gcc/html -C --build=x86_64-pc-cygwin --host=x86_64- 
pc-cygwin --target=x86_64-pc-cygwin --without-libiconv-prefix --without- 
libintl-prefix --libexecdir=/usr/lib --with-gcc-major-version-only --enable- 
shared --enable-shared-libgcc --enable-static --enable-version-specific- 
runtime-libs --enable-bootstrap --enable-__cxa_atexit --with-dwarf2 --with- 
tune=generic --enable-languages=c,c++,fortran,lto,objc,obj-c++ --enable- 
graphite --enable-threads=posix --enable-libatomic --enable-libgomp --enable- 
libquadmath --enable-libquadmath-support --disable-libssp --enable-libada -- 
disable-symvers --with-gnu-ld --with-gnu-as --with-cloog- 
include=/usr/include/cloog-isl --without-libiconv-prefix --without-libintl- 
prefix --with-system-zlib --enable-linker-build-id --with-default-libstdcxx- 
abi=gcc4-compatible --enable-libstdcxx-filesystem-ts
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 10.2.0 (GCC)

问题在于线程函数
t_work
,它正在调用
printf
。 根据您的平台,
printf
不一定是重新进入者。 在VisualStudio环境中,
printf
可能受到一些互斥锁的保护,一切正常。 但有了GCC及其libc,I/O函数中可能会发生竞争

解决方案:使用互斥来保护
printf
。 例如:

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

#define THREAD_COUNT 10
static CRITICAL_SECTION mutex;

DWORD WINAPI t_work(LPVOID param) {
    EnterCriticalSection(&mutex);
    printf("%d\n", *((int*)param));
    LeaveCriticalSection(&mutex);
    return 0;
}

int main() {
    InitializeCriticalSection(&mutex);
    DWORD* thread_id = malloc(THREAD_COUNT * sizeof(DWORD));
    HANDLE* threads = malloc(THREAD_COUNT * sizeof(HANDLE));
...
#包括
#包括
#包括
#定义线程计数10
静态临界段互斥;
DWORD WINAPI t_工作(LPVOID参数){
EnterCriticalSection(&mutex);
printf(“%d\n”,*((int*)参数));
leveCriticalSection(&mutex);
返回0;
}
int main(){
初始化CriticalSection(&mutex);
DWORD*线程id=malloc(线程计数*sizeof(DWORD));
HANDLE*threads=malloc(THREAD_COUNT*sizeof(HANDLE));
...

我认为您的指针算法不正确。您不想改用数组吗?@我将无法重现您的错误。您的代码(带或不带
返回0
)使用clang cl或MSVC在VS-2019上按预期运行。我仍然认为使用普通数组进行推理要简单得多。@Will-print
printf(++%x>%u\n),GetCurrentThreadId(),*((int*)param));
和闭环
printf(--%x>%u\n),thread\u id[I],data[I])是的!我是对的,问题在于
printf
。我会写一个答案。这个答案很准确!
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

#define THREAD_COUNT 10
static CRITICAL_SECTION mutex;

DWORD WINAPI t_work(LPVOID param) {
    EnterCriticalSection(&mutex);
    printf("%d\n", *((int*)param));
    LeaveCriticalSection(&mutex);
    return 0;
}

int main() {
    InitializeCriticalSection(&mutex);
    DWORD* thread_id = malloc(THREAD_COUNT * sizeof(DWORD));
    HANDLE* threads = malloc(THREAD_COUNT * sizeof(HANDLE));
...