zoukankan      html  css  js  c++  java
  • Linux内核多线程——补充(各种平台下的多线程)

    这里主要实现两个线程间通信,当flag = 10 之后通知另外一个线程(也就是“Linux内核多线程(二)”中的程序的各种平台实现)。

    首先是C++ 11 的方式:

    #include <thread>
    #include <iostream>
    #include <mutex>
    #include <queue>
    #include <condition_variable>
    #include <atomic>
    
    using namespace std;
    const int M = 10;
    
    int main()
    {
        mutex lockBuffer; 
         
        int flag = 0;
        bool stop = false;
        int count = 0;
    
        condition_variable_any recv_task_cond;
    
        condition_variable_any RecieveTask_cond;   
    
        thread recv_task([&]()
        { 
            while(true)
            {
    
                    std::this_thread::sleep_for (chrono::milliseconds (1000));
                    lockBuffer.lock ();
    
                    if(stop)
                    {
                        lockBuffer.unlock();
                        RecieveTask_cond.notify_one();
                        break;
                    }
    
                    if (flag == M)
    
                    {
    
                        cout<< "recv task try to wake up RecieveTask! "<<endl;
                        count++;
                        lockBuffer.unlock ();
                        RecieveTask_cond.notify_one ();
                        
                    }
    
                    else
                    {
                        flag++;
                        lockBuffer.unlock ();
                    }
    
            }
            cout<< "recv_task exit"<<endl;
    
        } );
    
    
        thread RecieveTask([&]()
    
        {
    
            while(true)
                {
                    std::this_thread::sleep_for (chrono::milliseconds (15));   
    
                    cout<<"In Recieve Task !" <<endl;
                    lockBuffer.lock ();
    
                    if(flag != M)
                    {
    
                        RecieveTask_cond.wait(lockBuffer);
                    }
    
                    if(stop)
                    {
                        lockBuffer.unlock();
                        recv_task_cond.notify_one();
                        break;
                    }
    
                    cout<<"WAKE UP  "<< count <<" times \t"<<" FLAG = " << flag <<endl;
                    cout<<endl;
    
                    flag = 0;
                    
                    lockBuffer.unlock ();
                    recv_task_cond.notify_one ();
                }
            cout<< "Recieve Task exit "<<endl;
    
        } );
    
        cout<< "Press Enter to stop "<<endl;
        getchar();
        stop = true;
    
        recv_task.join();
        RecieveTask.join();
    
        cout<<"Main Thread"<<endl;
    
        return 0;
    
    }

    运行结果:

    下面是使用windows提过的API来实现的方式:

    #include <stdio.h>
    #include <conio.h>
    #include <process.h>
    #include <windows.h>
    HANDLE  g_hThreadEvent,g_hevent;
    int flag = 0;
    CRITICAL_SECTION g_Critical;
    
    unsigned int __stdcall recv_task(void *pPM)
    {
        
        printf("%s 启动\n", (PSTR)pPM);
        while(1)
        {
            Sleep(1000);
            EnterCriticalSection(&g_Critical);
            printf("flag = %d\n", flag++);
            if(flag == 10)
                SetEvent(g_hThreadEvent);
    
            LeaveCriticalSection(&g_Critical);
        }
        return 0;
    }
    
    unsigned int __stdcall RecieveTask(void *pPM)
    {
        printf("%s 启动\n", (PSTR)pPM);
        while(1)
        {
            WaitForSingleObject(g_hThreadEvent, INFINITE);
            EnterCriticalSection(&g_Critical);
            Sleep(5000);
    
            printf("wake up flag = %d\n", flag);
            ResetEvent(g_hThreadEvent);
    
            flag = 0;
            LeaveCriticalSection(&g_Critical);
        }
        return 0;
    }
    int main()
    {
    
        InitializeCriticalSection(&g_Critical);
        
        g_hThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
        g_hevent = CreateEvent(NULL,FALSE,FALSE,NULL);
        HANDLE h[2];
        SetEvent(g_hevent);
        h[0] = (HANDLE)_beginthreadex(NULL, 0, recv_task, "recv_task", 0, NULL);
        
        h[1] = (HANDLE)_beginthreadex(NULL, 0, RecieveTask, "RecieveTask", 0, NULL);
    
        WaitForMultipleObjects(2,h,TRUE,INFINITE);
        
        CloseHandle(g_hThreadEvent);
        return 0;
    }

    运行结果:

    最后是使用posix 线程库实现的方式:

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    
    enum bool{FALSE = 0, TRUE = !FALSE};
    int stop;
    
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*初始化互斥锁*/
    pthread_cond_t cond = PTHREAD_COND_INITIALIZER;/*初始化条件变量*/
    
    void *RecieveTask(void *);
    void *recv_task(void *);
    
    int i = 0;
    
    int main()
    {
        pthread_t RT;
        pthread_t r_t;
        stop = TRUE;
    
        pthread_create(&RT,NULL,RecieveTask,(void *)NULL);/*创建进程RecieveTask*/
        pthread_create(&r_t,NULL,recv_task,(void *)NULL); /*创建进程recv_task*/
        
        getchar();
        stop = FALSE;
        //printf("STOP\n");
        
        pthread_join(RT, NULL);/*等待进程recv_task结束*/
        
        printf("BACK IN MAIN \n");
    
        pthread_mutex_destroy(&mutex);
        pthread_cond_destroy(&cond);
    
        
        return 0;
    }
    
    void *recv_task(void *junk)
    {
    
        while(stop)
        {
            pthread_mutex_lock(&mutex);/*锁住互斥量*/
    /*
            if(stop)
            {
                pthread_cond_signal(&cond);
                printf("END recv_task\n");
                break;
            }
    */
    
            if(i == 10)
                {
                    pthread_cond_signal(&cond);/*条件改变,发送信号,通知t_b进程*/
                    pthread_cond_wait(&cond,&mutex);
                }    
            else
                printf("recv_task: %d \n",i++);
    
            pthread_mutex_unlock(&mutex);/*解锁互斥量*/
    
            sleep(1);
    
        }
        pthread_cond_signal(&cond);
        printf("recv_task exit \n");
    }
    
    void *RecieveTask(void *junk)
    {
    
        while(stop)
        {
    
            pthread_mutex_lock(&mutex);
    
            if(i != 10)
                pthread_cond_wait(&cond,&mutex);/*等待*/
            if(!stop)
            {    
                printf("END RecieveTask \n");
                break;
            }
    
            printf("wake up RecieveTask: %d \n",i);
            i = 0;
            pthread_cond_signal(&cond);
            pthread_mutex_unlock(&mutex);
    
            sleep(1);
    
        }
        printf("RecieveTask exit \n");
    }

    运行结果为:

    本来还想写一个vxworks下的多线程实现方式(可以通过taskSpawn()函数来创建线程,使用MSG_Q_ID来通信),但是windriver卸载了。。。

  • 相关阅读:
    (转)用Ajax技术让IE Web Control Tree View实现大数据量读取
    您试图从目录中执行CGI、ISAPI 或其他可执行程序,但该目录不允许执行程序
    oracle数据库中ORA28000: the account is locked问题
    C#动态生成html页面
    oracle 用户权限解释
    HCPC2013校赛训练赛 2
    ZOJ2770 Burn the Linked Camp 差分约束
    POJ2570 Fiber Network 状态压缩+floyd
    ZOJ3088 Easter Holidays 最短路
    POJ1364 King 差分约束
  • 原文地址:https://www.cnblogs.com/zhuyp1015/p/2549973.html
Copyright © 2011-2022 走看看