zoukankan      html  css  js  c++  java
  • C语言多线程编程一

    1. Windows下同时打开多个对话框:

    #include <Windows.h>
    #include <process.h>    //创建线程
    
    void runmsg(void *p)
    {
        MessageBoxA(0, "hello world", "hello china", 0);
    
    }
    
    void main()
    {
        _beginthread(runmsg, 0, NULL);    //启动线程,函数地址,把函数当做线程的入口点
        _beginthread(runmsg, 0, NULL);
        _beginthread(runmsg, 0, NULL);
        _beginthread(runmsg, 0, NULL);
    
        system("pause");
    }

     2. 多线程实现同步和异步:

    #include <Windows.h>
    #include <stdlib.h>
    
    //typedef unsigned long       DWORD;
    //#define WINAPI      __stdcall 标准的呼叫
    //typedef void far            *LPVOID;
    DWORD WINAPI MyMseg(LPVOID lp)
    {
        MessageBoxA(0, "hello", "china", 0);
    }
    void main() { HANDLE hthread; DWORD threadid; //保存线程编号 //异步执行: //for (int i = 0; i < 5; i++) //{ // hthread = CreateThread( // NULL, //安全属性 // NULL, //堆栈大小 // MyMseg, //线程的入口点 // NULL, //函数的参数 // 0, //立刻执行 // &threadid //保存线程的id // ); //} //多线程实现同步: for (int i = 0; i < 5; i++) { hthread = CreateThread( NULL, //安全属性 NULL, //堆栈大小 MyMseg, //线程的入口点 NULL, //函数的参数 0, //立刻执行 &threadid //保存线程的id ); WaitForSingleObject(hthread, INFINITE); //等待 CloseHandle(hthread); //关闭线程 } system("pause"); }
    #include <stdio.h>
    #include <stdlib.h>
    #include <process.h>
    #include <Windows.h>
    
    void run(void *p)
    {
        int *px = p;
        printf("线程编号%d
    ", *px);
    }
    
    void main()
    {
        int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
        for (int i = 0; i < 10; i++)
        {
            HANDLE hd = (HANDLE) _beginthread(run, 0, &a[i]);    //MyThread线程编号
            WaitForSingleObject(hd, INFINITE);                    //单线程
            //WaitForMultipleObjects()        //多线程
        }
    
        system("pause");
    }

    3. 多线程检索:

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>      //生成随机数
    #include <process.h>
    
    int isfind = 0;        //找到设置为1,其他线程就不再查找
    
    struct findInfo
    {
        int *pstart;    //线程检索的首地址
        int length;     //检索的数据长度
        int findNum;    //需要查找的数据 
        int id;         //线程的编号
    };
    
    void findIt(void *p)
    {
        struct findInfo *ps = p;    //保存地址
        printf("
    线程%d开始查找
    ", ps->id);
    
        //遍历首地址,长度为10个元素
        for (int *pf = ps->pstart; pf < ps->pstart + ps->length; pf++)
        {
            if (isfind == 1)
            {
                printf("线程%d结束查找,其他线程已经找到
    ", ps->id);
                return;
    
            }
    
            if (*pf == ps->findNum)
            {
                printf("线程%d结束查找,找到数据%d地址%p
    ", ps->id, *pf, pf);
                isfind = 1;
                return;
            }
    
        }
    
        printf("线程%d结束查找
    ", ps->id);
    
    }
    
    void main()
    {
        int a[100] = { 0 };
        time_t ts;
        unsigned int data = time(&ts);
        srand(data);    //随机数种子
    
        for (int i = 0; i < 100; i++)
        {
            a[i] = rand() % 100;
            printf("%4d", a[i]);
            if ((i+1) % 10 == 0)    //每10个打印一行
            {
                printf("
    ");
            }
        }
    
        int num;
        printf("输入要查询的数:
    ");
        scanf("%d", &num);
    
        struct findInfo info[10];    //结构体数组,保存每个线程要查找的信息
        for (int i = 0; i < 10;i++)
        {
            info[i].pstart = a + 10 * i;
            info[i].length = 10;
            info[i].findNum = num;
            info[i].id = i;
    
            _beginthread(findIt, 0, &info[i]);    //调用线程
        }
    
        system("pause");
    }

     4. 多线程切割:

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #include <Windows.h>
    #include <time.h>        //生成随机数
    #include <process.h>
    
    int isfind = 0;        //找到设置为1,其他线程就不再查找
    
    struct findInfo
    {
        int *pstart;    //线程检索的首地址
        int length;        //检索的数据长度
        int findNum;    //需要查找的数据 
        int id;            //线程的编号
    };
    
    #define M 100    //数据
    #define N 8        //线程数量
    
    void findIt(void *p)
    {
        struct findInfo *ps = p;    //保存地址
        printf("
    线程%d开始查找
    ", ps->id);
    
        //遍历首地址,长度为10个元素
        for (int *pf = ps->pstart; pf < ps->pstart + ps->length; pf++)
        {
            if (isfind == 1)
            {
                printf("线程%d结束查找,其他线程已经找到
    ", ps->id);
                return;
    
            }
    
            if (*pf == ps->findNum)
            {
                printf("线程%d结束查找,找到数据%d地址%p
    ", ps->id, *pf, pf);
                isfind = 1;
                return;
            }
        }
    
        printf("线程%d结束查找
    ", ps->id);
    }
    
    void main()
    {
        int a[100] = { 0 };
        time_t ts;
        unsigned int data = time(&ts);
        srand(data);    //随机数种子
    
        for (int i = 0; i < 100; i++)
        {
            a[i] = rand() % 100;
            printf("%4d", a[i]);
            if ((i+1) % 10 == 0)    //每10个打印一行
            {
                printf("
    ");
            }
        }
    
        int num;
        printf("输入要查询的数:
    ");
        scanf("%d", &num);
    
        struct findInfo info[N];    //结构体数组,保存每个线程要查找的信息
        if (M%N == 0)    //前面能整除的情况
        {
            for (int i = 0; i < N; i++)
            {
                info[i].pstart = a + M/N * i;
                info[i].length = M/N;
                info[i].findNum = num;
                info[i].id = i;
                HANDLE hd = _beginthread(findIt, 0, &info[i]);
            }
        }
        else            //不能整除的情况
        {
            for (int i = 0; i < N-1; i++)
            {
                info[i].pstart = a + M / (N-1) * i;
                info[i].length = M / (N - 1);
                info[i].findNum = num;
                info[i].id = i;
                HANDLE hd = _beginthread(findIt, 0, &info[i]);
            }
            //info[N-1];
            int i = N - 1;
            info[i].pstart = a + M / (N - 1) * i;
            info[i].length = M % (N - 1);
            info[i].findNum = num;
            info[i].id = i;
            HANDLE hd = _beginthread(findIt, 0, &info[i]);
        }
    
        system("pause");
    }

     5. 多线程冲突:

    #include <stdio.h>
    #include <stdlib.h>
    #include <process.h>
    #include <Windows.h>
    #include <time.h>
    
    CRITICAL_SECTION cs;    //临界区,全局
    
    int num = 0;            //全局变量,多线程同时访问会发生冲突
    
    //10 *     100 * 100
    DWORD WINAPI myfun(void *p)
    {
        for (int i = 0; i < 100; i++)
        {
            EnterCriticalSection(&cs);    //进入临界区
            num++;
            LeaveCriticalSection(&cs);    //离开临界区
            //Sleep(10);
        }
        return 0;
    }
    
    void main()
    {
        time_t start, end;
        time(&start);
    
        HANDLE hd[100];
        for (int i = 0; i < 100; i++)
        {
            hd[i] = CreateThread(NULL, 0, myfun, NULL, 0, NULL);
            //hd[i] = _beginthread(myfun, 0, NULL);    //线程数组,数组的每一个元素都是一个线程
            //WaitForSingleObject(hd[i], INFINITE);    //等待单个的线程结束(同步)
        }
        WaitForMultipleObjects(100, hd, TRUE, INFINITE);    //等待所有线程退出
        
        time(&end);
        printf("%f
    ", difftime(end, start));
    
        printf("%d
    ", num);
        
        DeleteCriticalSection(&cs);
        system("pause");
    }

    6. 多线程的操作:

    #include <stdio.h>
    #include <stdlib.h>
    #include <process.h>
    #include <Windows.h>
    
    //_beginthread CreateThread 创建线程
    //_endthread ExitThread 内部结束线程   TerminateThread 外部强制结束
    //SuspendThread冻结    ResumeThread解冻     
    
    DWORD WINAPI fun(void *p)
    {
        int i = 0;
        while (++i)
        {
            printf("%d
    ", i);
    
            if (i > 8000)
            {
                //_endthread();    //用于线程内部退出
                ExitThread(0);    //同上
            }
    
        }
    
    
        return 0;
    }
    
    //主线程,主导作用,管理调度其他线程
    void main()
    {
        HANDLE hd = CreateThread(NULL, 0, fun, NULL, 0, NULL);
    
        system("pause");
        SuspendThread(hd);    //冻结线程
        system("pause");
        ResumeThread(hd);    //解冻线程
        system("pause");
    
        
        TerminateThread(hd,0);    //外部强行结束线程
    
        system("pause");
    }

    7. 临界区 Critical Section:

    #include <stdio.h>
    #include <stdlib.h>
    #include <process.h>
    #include <Windows.h>
    
    #define N 10    //#define N 100 临界区最大线程是64
    int num = 0;
    
    CRITICAL_SECTION cs1;    //定义临界区,为结构体变量
    CRITICAL_SECTION cs2;
    
    DWORD WINAPI add(void *p)
    {
        EnterCriticalSection(&cs1);    //进入临界区,写在for循环外,节省了在循环中反复进入和退出临界区
        for (int i = 0; i < 10000; i++)
        {
            //EnterCriticalSection(&cs1);    
            num++;
            //LeaveCriticalSection(&cs1);    
        }
        LeaveCriticalSection(&cs1);    //退出临界区
    
        return 0;
    }
    
    DWORD WINAPI sub(void *p)
    {
        EnterCriticalSection(&cs2);    //进入临界区,写在for循环外,节省了在循环中反复进入和退出临界区
        for (int i = 0; i < 10000; i++)
        {
            num--;    
        }
        LeaveCriticalSection(&cs2);    //退出临界区
    
        return 0;
    }
    
    void main()
    {
        InitializeCriticalSection(&cs1);    //初始化临界区结构体
        InitializeCriticalSection(&cs2);
    
        {
            HANDLE hd[N];
            for (int i = 0; i < N; i++)
            {
                hd[i] = CreateThread(NULL, 0, add, NULL, 0, NULL);    //创建线程
                //WaitForSingleObject(hd[i], INFINITE);
            }
            WaitForMultipleObjects(N, hd, TRUE, INFINITE);    //等待全部线程退出
    
            printf("num=%d
    ", num);
        }
    
        {
            HANDLE hd[N];
            for (int i = 0; i < N; i++)
            {
                hd[i] = CreateThread(NULL, 0, sub, NULL, 0, NULL);    //创建线程
                //WaitForSingleObject(hd[i], INFINITE);
            }
            WaitForMultipleObjects(N, hd, TRUE, INFINITE);    //等待全部线程退出
    
            printf("num=%d
    ", num);
        }
    
        DeleteCriticalSection(&cs1);    //释放临界区
        DeleteCriticalSection(&cs2);
    
        system("pause");
    }

     8. 线程通信-事件机制 event:

    #include <stdio.h>
    #include <stdlib.h>
    #include <Windows.h>
    
    HANDLE event[3] = {0};    //事件
    HANDLE hd[3] = { 0 };    //线程数组
    
    DWORD WINAPI firstthread(void *p)
    {
        MessageBoxA(0, "1", "1", 0);
        printf("第1个线程执行完成.
    ");
    
        SetEvent(event[0]);                            //设置event信号
        return 0;
    }
    
    DWORD WINAPI secondthread(void *p)
    {
        WaitForSingleObject(event[0], INFINITE);    //等待event信号出现,才执行下一步
        
        MessageBoxA(0, "2", "2", 0);
    
        printf("第2个线程执行完成.
    ");
        return 0;
    }
    
    void main()
    {
        event[0] = CreateEvent(NULL, TRUE, FALSE, NULL);    //创建事件
        event[1] = CreateEvent(NULL, TRUE, FALSE, NULL);
    
        hd[0] = CreateThread(NULL, 0, firstthread, NULL, 0, NULL);    //创建线程
        hd[1] = CreateThread(NULL, 0, secondthread, NULL, 0, NULL);
    
        WaitForMultipleObjects(2, hd, TRUE, INFINITE);
        printf("全部完成!
    ");
    
        system("pause");
    }
    #define _CRT_SECURE_NO_WARNINGS
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <Windows.h>
    #include <memory.h>
    
    HANDLE event[4] = { 0 };    //事件
    HANDLE hd[3] = { 0 };        //线程数组
    char str[1024] = { 0 };        //代表聊天内容的缓冲区
    
    CRITICAL_SECTION(cs);        //临界区
    
    //0  张通知媒婆
    //1  媒婆发给李
    //2  李通知媒婆
    //3  媒婆发给张
    DWORD WINAPI Zhang(void *p)
    {
        int i = 1;
    
        EnterCriticalSection(&cs);    //进入临界区
        memset(str, '', 1024);
        sprintf(str, "张第%d次说:I love you Li
    ", i);
        LeaveCriticalSection(&cs);    //离开临界区
    
        Sleep(1000);
        SetEvent(event[0]);
        
        while (++i)
        {
            WaitForSingleObject(event[3], INFINITE);
    
            EnterCriticalSection(&cs);    //进入临界区
            memset(str, '', 1024);
            sprintf(str, "张第%d次说:I love you Li
    ", i);
            LeaveCriticalSection(&cs);    //离开临界区
    
            Sleep(1000);
            SetEvent(event[0]);
            
        }
    
        return 0;
    }
    
    DWORD WINAPI Li(void *p)
    {
        int i = 0;
        while (++i)
        {
            WaitForSingleObject(event[1], INFINITE);
    
            EnterCriticalSection(&cs);    //进入临界区
            memset(str, '', 1024);
            sprintf(str,"李第%d次说:I love you too
    ", i);
            LeaveCriticalSection(&cs);    //离开临界区
    
            Sleep(1000);
            SetEvent(event[2]);
            
        }
    
        return 0;
    }
    
    DWORD WINAPI show(void *p)
    {
        int i = 0;
        while (++i)
        {
            WaitForSingleObject(event[0], INFINITE);
    
            EnterCriticalSection(&cs);    //进入临界区
            printf("媒婆传递:%s
    ", str);
            LeaveCriticalSection(&cs);    //离开临界区
    
            Sleep(1000);
            SetEvent(event[1]);
    
    
            WaitForSingleObject(event[2], INFINITE);
            EnterCriticalSection(&cs);
            printf("媒婆传递:%s
    ", str);
            LeaveCriticalSection(&cs);
            
            Sleep(1000);
            SetEvent(event[3]);
        }
    
        return 0;
    }
    
    
    void main()
    {
        InitializeCriticalSection(&cs);
    
        event[0] = CreateEvent(NULL, TRUE, FALSE, NULL);    //创建事件
        event[1] = CreateEvent(NULL, TRUE, FALSE, NULL);
        event[2] = CreateEvent(NULL, TRUE, FALSE, NULL);
        event[3] = CreateEvent(NULL, TRUE, FALSE, NULL);
    
        hd[0] = CreateThread(NULL, 0, Zhang, NULL, 0, NULL);    //创建线程
        hd[1] = CreateThread(NULL, 0, Li, NULL, 0, NULL);
        hd[2] = CreateThread(NULL, 0, show, NULL, 0, NULL);
    
        WaitForMultipleObjects(2, hd, TRUE, INFINITE);
        printf("全部完成!
    ");
    
        DeleteCriticalSection(&cs);
    
        system("pause");
    }

    9. 线程互斥量 mutex:

    #include <stdio.h>
    #include <stdlib.h>
    #include <Windows.h>
    
    int num = 0;
    
    HANDLE mutex = NULL;    //指针
    
    DWORD WINAPI add(void *p)
    {
        WaitForSingleObject(mutex, INFINITE);
        for (int i = 0; i < 100000; i++)
        {
            num++;
        }
        ReleaseMutex(mutex);
    
        return 0;
    }
    
    void main()
    {
        mutex = CreateMutex(NULL, FALSE, NULL);    //创建互斥量
        if (mutex == NULL)
        {
            //创建失败
        }
            
        HANDLE hd[10];    //线程互斥,同一个互斥量只能解决64个线程
    
        for (int i = 0; i < 10; i++)    //创建10个线程
        {
            hd[i] = CreateThread(NULL, 0, add, NULL, 0, NULL);
            if (mutex == NULL)
            {
                //创建失败
            }    
        }
    
        WaitForMultipleObjects(10, hd, TRUE, INFINITE);
    
        printf("%d
    ", num);
    
        for (int i = 0; i < 10; i++)    //关闭每一个线程资源
        {
            CloseHandle(hd[i]);
        }
    
        CloseHandle(mutex);        //关闭互斥量
    
        system("pause");
    }

     10. 原子变量 valatile :

    #include <stdio.h>
    #include <stdlib.h>
    #include <limits.h>
    #include <Windows.h>
    
    void main0401()
    {
        //release 优化
        //volatile 原子操作 强制读内存 不考虑副本
        for (volatile int i = 0; i < INT_MAX; i++)
        {
    
        }
    
        printf("over");
        system("pause");
    }
    
    volatile int num = 20;        //现代编译器做了优化,加不加volatile是一样的
    
    DWORD WINAPI msg(void *p)    //
    {
        int *px = (int *)p;
    
        while (1)
        {
            int data = *px;            //强制读内存
            printf("%d
    ", data);
    
            Sleep(1000);
        }
    }
    
    DWORD WINAPI cmsg(void *p)    //
    {
        int *px = (int *)p;
    
        while (1)
        {
    
            *px += 1;
    
            Sleep(10000);
        }
    }
    
    void main()
    {
        CreateThread(NULL, 0, msg, &num, 0, NULL);
        CreateThread(NULL, 0, cmsg, &num, 0, NULL);
    
        printf("over");
        system("pause");
    }
    #include <stdio.h>
    #include <stdlib.h>
    #include <limits.h>
    #include <Windows.h>
    
    int num = 0;    //多个线程同时访问一个变量会发生冲突,同时写入
    //线程安全:一个变量是线程安全,多线程同时读写没有误差
    //临界区(Critical Section)、事件机制(event)、互斥量(Mutex) 
    //原子操作的速度要快于 临界区(Critical Section)、事件机制(event)、互斥量(Mutex) 
    DWORD WINAPI runX(void *p)    
    {
        for (int i = 0; i < 10000; i++)
        {
            //num++;
            InterlockedIncrement(&num);    //num++保证是完整操作,我操作完成了后续才能继续执行
        }
    
        return 0;
    }
    
    void main()
    {
        HANDLE hd[50];
        for (int i = 0; i < 50; i++)
        {
            hd[i] = CreateThread(NULL, 0, runX, NULL, 0, NULL);
        }
        WaitForMultipleObjects(50, hd, TRUE, INFINITE);
    
        printf("%d
    ", num);
    
        system("pause");
    }

     11. 定时器 timer :

    #include <stdio.h>
    #include <stdlib.h>
    #include <Windows.h>
    
    //单独定时器只能用于同步通信
    void main0601()
    {
        HANDLE timer = CreateWaitableTimer(NULL, TRUE, NULL);    //创建定时器
        if (timer == NULL)
        {
            return;
        }
    
        LARGE_INTEGER time;            //
        time.QuadPart = -20000000;    //2秒
        //单位是10^-7秒  0.1微秒
        SetWaitableTimer(timer, &time, 0, NULL, 0, NULL);    //设置定时器等待2秒
    
        if (WaitForSingleObject(timer, INFINITE) == WAIT_OBJECT_0)
        {
            printf("等待成功!
    ");
        }
        else
        {
            printf("等待失败!
    ");
        }
    
        system("pause");
    }
    
    HANDLE timer;
    
    DWORD WINAPI go1(void *p)
    {
        MessageBoxA(0, "1", "1", 0);
    
        timer = CreateWaitableTimer(NULL, TRUE, NULL);    //创建定时器
        LARGE_INTEGER time;            //
        time.QuadPart = -50000000;    //2秒
                                    //单位是10^-7秒  0.1微秒
        SetWaitableTimer(timer, &time, 0, NULL, 0, NULL);    //设置定时器等待2秒
    }
    
    DWORD WINAPI go2(void *p)
    {
        WaitForSingleObject(timer, INFINITE) == WAIT_OBJECT_0;
        MessageBoxA(0, "2", "2", 0);
        printf("等待成功!
    ");
    }
    
    void main()
    {
        HANDLE hd = CreateThread(NULL, 0, go1, NULL, 0, NULL);
    
        WaitForSingleObject(hd, INFINITE);
    
        if (WaitForSingleObject(timer, INFINITE) == WAIT_OBJECT_0)
        {
            CreateThread(NULL, 0, go2, NULL, 0, NULL);
            printf("等待成功!
    ");
        }
        else
        {
            printf("等待失败!
    ");
        }
    
        system("pause");
    }
  • 相关阅读:
    算法
    数据结构
    数据表与简单java类(一对多)
    引用传递
    二叉排序树 C++
    二叉树 C++
    基数排序
    快速排序
    堆排序
    归并排序
  • 原文地址:https://www.cnblogs.com/si-lei/p/9480796.html
Copyright © 2011-2022 走看看