windows下线程同步【WaitForSingleObject、WaitForMultipleObjects、CRITICAL_SECTION(用户模式)、互斥量(内核模式)、信号量(内核模式)、事件对象(内核模式)】

WaitForSingleObject函数的使用

#include <stdio.h>
#include <windows.h>
#include <process.h>
unsigned WINAPI ThreadFunc(void *arg); int main(int argc, char *argv[]) { HANDLE hThread; DWORD wr; unsigned threadID; int param = 5; hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadFunc, (void *)&param, 0, &threadID); if((wr = WaitForSingleObject(hThread, INFINITE)) == WAIT_FAILED) { puts("thread wait error"); return -1; } printf("wait result: %s \n", (wr == WAIT_OBJECT_0) ? "signaled" : "time-out"); puts("end of main"); return 0; } unsigned WINAPI ThreadFunc(void *arg) { int i; int cnt = *((int *)arg); for(i = 0; i < cnt; i ++) { Sleep(1000); puts("running thread"); } return 0; }

WaitForMultipleObjects函数的使用(这个不会产生正确的结果)

#include <stdio.h>
#include <windows.h>
#include <process.h>
#define NUM_THREAD 50
unsigned WINAPI threadInc(void *arg);
unsigned WINAPI threadDec(void *arg);
long long num = 0;
int main(int argc, char *argv[])
{
    HANDLE  tHandles[NUM_THREAD];
    int i;
    printf("sizeof long long: %d \n", sizeof(long long));
    for(i = 0; i < NUM_THREAD; i ++)
    {
        if(i % 2)
            tHandles[i] = (HANDLE)_beginthreadex(NULL, 0, threadInc, NULL, 0, NULL);
        else
            tHandles[i] = (HANDLE)_beginthreadex(NULL, 0, threadDec, NULL, 0, NULL);
    }
    WaitForMultipleObjects(NUM_THREAD, tHandles, TRUE, INFINITE);
    printf("result: %lld \n", num);
    return 0;
}
unsigned WINAPI threadInc(void *arg)
{
    int i;
    for(i = 0; i < 50000000; i ++)
        num += 1;
    return 0;
}
unsigned WINAPI threadDec(void *arg)
{
    int i;
    for(i = 0; i < 50000000; i ++)
        num -= 1;
    return 0;
}

CRITICAL_SECTION的使用

#include <stdio.h>
#include <windows.h>
#include <process.h>
#define NUM_THREAD 50
unsigned WINAPI threadInc(void *arg);
unsigned WINAPI threadDec(void *arg);
long long num = 0;
CRITICAL_SECTION cs;
int main(int argc, char *argv[])
{
    HANDLE  tHandles[NUM_THREAD];
    int i;
    InitializeCriticalSection(&cs);
    for(i = 0; i < NUM_THREAD; i ++)
    {
        if(i % 2)
            tHandles[i] = (HANDLE)_beginthreadex(NULL, 0, threadInc, NULL, 0, NULL);
        else
            tHandles[i] = (HANDLE)_beginthreadex(NULL, 0, threadDec, NULL, 0, NULL);
    }
    WaitForMultipleObjects(NUM_THREAD, tHandles, TRUE, INFINITE);
    DeleteCriticalSection(&cs);
    printf("result: %lld \n", num);
    return 0;
}
unsigned WINAPI threadInc(void *arg)
{
    int i;
    EnterCriticalSection(&cs);
    for(i = 0; i < 50000000; i ++)
        num += 1;
    LeaveCriticalSection(&cs);
    return 0;
}
unsigned WINAPI threadDec(void *arg)
{
    int i;
    EnterCriticalSection(&cs);
    for(i = 0; i < 50000000; i ++)
        num -= 1;
    LeaveCriticalSection(&cs);
    return 0;
}

基于互斥量的同步

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

#define NUM_THREAD 50
unsigned WINAPI threadInc(void *arg);
unsigned WINAPI threadDec(void *arg);

long long num = 0;
HANDLE hMutex;

int main(int argc, char *argv[])
{
    HANDLE  tHandles[NUM_THREAD];
    int i;

    hMutex = CreateMutex(NULL, FALSE, NULL);
    for(i = 0; i < NUM_THREAD; i ++)
    {
        if(i % 2)
            tHandles[i] = (HANDLE)_beginthreadex(NULL, 0, threadInc, NULL, 0, NULL);
        else
            tHandles[i] = (HANDLE)_beginthreadex(NULL, 0, threadDec, NULL, 0, NULL);
    }

    WaitForMultipleObjects(NUM_THREAD, tHandles, TRUE, INFINITE);
    CloseHandle(hMutex);
    printf("result: %lld \n", num);
    return 0;
}

unsigned WINAPI threadInc(void *arg)
{
    int i;
    WaitForSingleObject(hMutex, INFINITE);
    for(i = 0; i < 50000000; i ++)
        num += 1;
    ReleaseMutex(hMutex);
    return 0;
}

unsigned WINAPI threadDec(void *arg)
{
    int i;
    WaitForSingleObject(hMutex, INFINITE);
    for(i = 0; i < 50000000; i ++)
        num -= 1;
    ReleaseMutex(hMutex);
    return 0;
}

基于信号量的同步

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

unsigned WINAPI Read(void *arg);
unsigned WINAPI Accu(void *arg);

static HANDLE semOne;
static HANDLE semTwo;
static int num;

int main(int argc, char *argv[])
{
    HANDLE  hThread1, hThread2;
    semOne = CreateSemaphore(NULL, 0, 1, NULL);
    semTwo = CreateSemaphore(NULL, 1, 1, NULL);

    hThread1 = (HANDLE)_beginthreadex(NULL, 0, Read, NULL, 0, NULL);
    hThread2 = (HANDLE)_beginthreadex(NULL, 0, Accu, NULL, 0, NULL);

    WaitForSingleObject(hThread1, INFINITE);
    WaitForSingleObject(hThread2, INFINITE);

    CloseHandle(semOne);
    CloseHandle(semTwo);
    return 0;
}

unsigned WINAPI Read(void *arg)
{
    int i;
    for(i = 0; i < 5; i ++)
    {
        fputs("Input num: ", stdout);
        WaitForSingleObject(semTwo, INFINITE);
        scanf("%d", &num);
        ReleaseSemaphore(semOne, 1, NULL);
    }
    return 0;
}

unsigned WINAPI Accu(void *arg)
{
    int sum = 0, i;
    for(i = 0; i < 5; i ++)
    {
        WaitForSingleObject(semOne, INFINITE);
        sum += num;
        ReleaseSemaphore(semTwo, 1, NULL);
    }
    printf("Result: %d \n", sum);
    return 0;
}

基于事件对象的同步

#include <stdio.h>
#include <windows.h>
#include <process.h>
#define STR_LEN 100

unsigned WINAPI NumberOfA(void *arg);
unsigned WINAPI NumberOfOthers(void *arg);

static char str[STR_LEN];
static HANDLE hEvent;

int main(int argc, char *argv[])
{
    HANDLE  hThread1, hThread2;
    hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    hThread1 = (HANDLE)_beginthreadex(NULL, 0, NumberOfA, NULL, 0, NULL);
    hThread2 = (HANDLE)_beginthreadex(NULL, 0, NumberOfOthers, NULL, 0, NULL);

    fputs("Input string: ", stdout);
    fgets(str, STR_LEN, stdin);
    SetEvent(hEvent);

    WaitForSingleObject(hThread1, INFINITE);
    WaitForSingleObject(hThread2, INFINITE);
    ResetEvent(hEvent);
    CloseHandle(hEvent);
    return 0;
}

unsigned WINAPI NumberOfA(void *arg)
{
    int i, cnt = 0;
    WaitForSingleObject(hEvent, INFINITE);
    for(i = 0; str[i] != 0; i ++)
    {
        if(str[i] == 'A')
            cnt ++;
    }
    printf("num of A: %d \n", cnt);
    return 0;
}

unsigned WINAPI NumberOfOthers(void *arg)
{
    int i, cnt = 0;
    WaitForSingleObject(hEvent, INFINITE);
    for(i = 0; str[i] != 0; i ++)
    {
        if(str[i] != 'A')
            cnt ++;
    }
    printf("Number of others: %d \n", cnt - 1);
    return 0;
}

  

posted @ 2019-11-12 16:01  wisdomroc  阅读(369)  评论(0编辑  收藏  举报