新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论高级C/C++编程、代码重构(Refactoring)、极限编程(XP)、泛型编程等话题
    [返回] 中文XML论坛 - 专业的XML技术讨论区计算机技术与应用『 C/C++编程思想 』 → 多线程处理和区域设置 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 5712 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: 多线程处理和区域设置 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客楼主
    发贴心情 多线程处理和区域设置

    C 运行时库和标准 C++ 库都支持更改程序的区域设置。本主题讨论在多线程应用程序中使用这两个库的区域设置功能时出现的问题。

    备注
    使用 C 运行时库,您可以使用 _beginthread 和 _beginthreadex 函数创建多线程应用程序。本主题仅涵盖使用这些函数创建的多线程应用程序。有关更多信息,请参见 _beginthread, _beginthreadex。

    要使用 C 运行时库更改区域设置,请使用 setlocale 函数。在以前版本的 Visual C++ 中,此函数始终修改整个应用程序中的区域设置。现在,支持在每线程基础上设置区域设置。这是使用 _configthreadlocale 函数实现的。要指定该 setlocale 仅应更改当前线程中的区域设置,请在该线程中调用 _configthreadlocale(_ENABLE_PER_THREAD_LOCALE)。相反,调用 _configthreadlocale(_DISABLE_PER_THREAD_LOCALE) 将导致该线程使用全局区域设置,对该线程中 setlocale 的任何调用将更改未显式启用每线程区域设置的所有线程中的区域设置。

    要使用 C++ 运行时库更改区域设置,请使用 locale Class。通过调用 locale::global 方法,可以更改未显式启用每线程区域设置的每个线程中的区域设置。要更改应用程序的单个线程或部分的区域设置,只需在该线程或代码部分中创建 locale 对象的实例。

    说明:
    调用 locale::global 将同时更改标准 C++ 库和 C 运行时库的区域设置。但是,调用 setlocale 仅更改 C 运行时库的区域设置;标准 C++ 库不受影响。

    以下示例显示如何使用 setlocale 函数、locale Class 和 _configthreadlocale 函数在几个不同的方案中更改应用程序的区域设置。

    示例
    在此示例中,主线程生成两个子线程。第一个线程(线程 A)通过调用 _configthreadlocale(_ENABLE_PER_THREAD_LOCALE) 启用每线程区域设置。第二个线程(线程 B)与主线程一样,不启用每线程区域设置。然后,线程 A 继续使用 C 运行时库的 setlocale 函数更改区域设置。

    由于线程 A 启用了每线程区域设置,只有线程 A 中的 C 运行时库函数开始使用“法国”区域设置。线程 B 以及主线程中的 C 运行时库函数继续使用“C”区域设置。此外,由于 setlocale 并不影响标准 C++ 库区域设置,所有标准 C++ 库对象继续使用“C”区域设置。


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2008/8/11 8:21:00
     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客2
    发贴心情 
    // multithread_locale_1.cpp
    // compile with: /EHsc /MD
    #include <clocale>
    #include <cstdio>
    #include <locale>
    #include <process.h>
    #include <windows.h>

    #define NUM_THREADS 2
    using namespace std;

    unsigned __stdcall RunThreadA(void *params);
    unsigned __stdcall RunThreadB(void *params);

    BOOL localeSet = FALSE;
    HANDLE printMutex = CreateMutex(NULL, FALSE, NULL);

    int main()
    {
        HANDLE threads[NUM_THREADS];

        unsigned aID;
        threads[0] = (HANDLE)_beginthreadex(
            NULL, 0, RunThreadA, NULL, 0, &aID);

        unsigned bID;
        threads[1] = (HANDLE)_beginthreadex(
            NULL, 0, RunThreadB, NULL, 0, &bID);

        WaitForMultipleObjects(2, threads, TRUE, INFINITE);

        printf_s("[Thread main] Per-thread locale is NOT enabled.\n");
        printf_s("[Thread main] CRT locale is set to \"%s\"\n",
            setlocale(LC_ALL, NULL));
        printf_s("[Thread main] locale::global is set to \"%s\"\n",
            locale().name().c_str());

        CloseHandle(threads[0]);
        CloseHandle(threads[1]);
        CloseHandle(printMutex);

        return 0;
    }

    unsigned __stdcall RunThreadA(void *params)
    {
        _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
        setlocale(LC_ALL, "french");
        localeSet = TRUE;

        WaitForSingleObject(printMutex, INFINITE);
        printf_s("[Thread A] Per-thread locale is enabled.\n");
        printf_s("[Thread A] CRT locale is set to \"%s\"\n",
            setlocale(LC_ALL, NULL));
        printf_s("[Thread A] locale::global is set to \"%s\"\n\n",
            locale().name().c_str());
        ReleaseMutex(printMutex);

        return 1;
    }

    unsigned __stdcall RunThreadB(void *params)
    {
        while (!localeSet)
            Sleep(100);

        WaitForSingleObject(printMutex, INFINITE);
        printf_s("[Thread B] Per-thread locale is NOT enabled.\n");
        printf_s("[Thread B] CRT locale is set to \"%s\"\n",
            setlocale(LC_ALL, NULL));
        printf_s("[Thread B] locale::global is set to \"%s\"\n\n",
            locale().name().c_str());
        ReleaseMutex(printMutex);

        return 1;
    } 复制代码
    [Thread A] Per-thread locale is enabled.
    [Thread A] CRT locale is set to "French_France.1252"
    [Thread A] locale::global is set to "C"

    [Thread B] Per-thread locale is NOT enabled.
    [Thread B] CRT locale is set to "C"
    [Thread B] locale::global is set to "C"

    [Thread main] Per-thread locale is NOT enabled.
    [Thread main] CRT locale is set to "C"
    [Thread main] locale::global is set to "C"在此示例中,主线程生成两个子线程。第一个线程(线程 A)通过调用 _configthreadlocale(_ENABLE_PER_THREAD_LOCALE) 启用每线程区域设置。第二个线程(线程 B)与主线程一样,不启用每线程区域设置。然后,线程 A 继续使用标准 C++ 库的 locale::global 方法更改区域设置。

    由于线程 A 启用了每线程区域设置,只有线程 A 中的 C 运行时库函数开始使用“法国”区域设置。线程 B 以及主线程中的 C 运行时库函数继续使用“C”区域设置。但是,由于 locale::global 方法会“全局性地”更改区域设置,所有线程中的所有标准 C++ 库对象都开始使用“法国”区域设置。

    复制代码
    // multithread_locale_2.cpp
    // compile with: /EHsc /MD
    #include <clocale>
    #include <cstdio>
    #include <locale>
    #include <process.h>
    #include <windows.h>

    #define NUM_THREADS 2
    using namespace std;

    unsigned __stdcall RunThreadA(void *params);
    unsigned __stdcall RunThreadB(void *params);

    BOOL localeSet = FALSE;
    HANDLE printMutex = CreateMutex(NULL, FALSE, NULL);

    int main()
    {
        HANDLE threads[NUM_THREADS];

        unsigned aID;
        threads[0] = (HANDLE)_beginthreadex(
            NULL, 0, RunThreadA, NULL, 0, &aID);

        unsigned bID;
        threads[1] = (HANDLE)_beginthreadex(
            NULL, 0, RunThreadB, NULL, 0, &bID);

        WaitForMultipleObjects(2, threads, TRUE, INFINITE);

        printf_s("[Thread main] Per-thread locale is NOT enabled.\n");
        printf_s("[Thread main] CRT locale is set to \"%s\"\n",
            setlocale(LC_ALL, NULL));
        printf_s("[Thread main] locale::global is set to \"%s\"\n",
            locale().name().c_str());

        CloseHandle(threads[0]);
        CloseHandle(threads[1]);
        CloseHandle(printMutex);

        return 0;
    }

    unsigned __stdcall RunThreadA(void *params)
    {
        _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
        locale::global(locale("french"));
        localeSet = TRUE;

        WaitForSingleObject(printMutex, INFINITE);
        printf_s("[Thread A] Per-thread locale is enabled.\n");
        printf_s("[Thread A] CRT locale is set to \"%s\"\n",
            setlocale(LC_ALL, NULL));
        printf_s("[Thread A] locale::global is set to \"%s\"\n\n",
            locale().name().c_str());
        ReleaseMutex(printMutex);

        return 1;
    }

    unsigned __stdcall RunThreadB(void *params)
    {
        while (!localeSet)
            Sleep(100);

        WaitForSingleObject(printMutex, INFINITE);
        printf_s("[Thread B] Per-thread locale is NOT enabled.\n");
        printf_s("[Thread B] CRT locale is set to \"%s\"\n",
            setlocale(LC_ALL, NULL));
        printf_s("[Thread B] locale::global is set to \"%s\"\n\n",
            locale().name().c_str());
        ReleaseMutex(printMutex);

        return 1;
    } 复制代码
    [Thread A] Per-thread locale is enabled.
    [Thread A] CRT locale is set to "French_France.1252"
    [Thread A] locale::global is set to "French_France.1252"

    [Thread B] Per-thread locale is NOT enabled.
    [Thread B] CRT locale is set to "C"
    [Thread B] locale::global is set to "French_France.1252"

    [Thread main] Per-thread locale is NOT enabled.
    [Thread main] CRT locale is set to "C"
    [Thread main] locale::global is set to "French_France.1252"在此示例中,主线程生成两个子线程。第一个线程(线程 A)通过调用 _configthreadlocale(_ENABLE_PER_THREAD_LOCALE) 启用每线程区域设置。第二个线程(线程 B)与主线程一样,不启用每线程区域设置。然后,线程 B 继续使用 C 运行时库的 setlocale 函数更改区域设置。

    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2008/8/11 8:21:00
     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客3
    发贴心情 
    由于线程 B 没有启用每线程区域设置,线程 B 以及主线程中的 C 运行时库函数开始使用“法国”区域设置。由于线程 A 启用了每线程区域设置,线程 A 中的 C 运行时库函数继续使用“C”区域设置。此外,由于 setlocale 并不影响标准 C++ 库区域设置,所有标准 C++ 库对象继续使用“C”区域设置。

    复制代码
    // multithread_locale_3.cpp
    // compile with: /EHsc /MD
    #include <clocale>
    #include <cstdio>
    #include <locale>
    #include <process.h>
    #include <windows.h>

    #define NUM_THREADS 2
    using namespace std;

    unsigned __stdcall RunThreadA(void *params);
    unsigned __stdcall RunThreadB(void *params);

    BOOL localeSet = FALSE;
    BOOL configThreadLocaleCalled = FALSE;
    HANDLE printMutex = CreateMutex(NULL, FALSE, NULL);

    int main()
    {
        HANDLE threads[NUM_THREADS];

        unsigned aID;
        threads[0] = (HANDLE)_beginthreadex(
            NULL, 0, RunThreadA, NULL, 0, &aID);

        unsigned bID;
        threads[1] = (HANDLE)_beginthreadex(
            NULL, 0, RunThreadB, NULL, 0, &bID);

        WaitForMultipleObjects(2, threads, TRUE, INFINITE);

        printf_s("[Thread main] Per-thread locale is NOT enabled.\n");
        printf_s("[Thread main] CRT locale is set to \"%s\"\n",
            setlocale(LC_ALL, NULL));
        printf_s("[Thread main] locale::global is set to \"%s\"\n",
            locale().name().c_str());

        CloseHandle(threads[0]);
        CloseHandle(threads[1]);
        CloseHandle(printMutex);

        return 0;
    }

    unsigned __stdcall RunThreadA(void *params)
    {
        _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
        configThreadLocaleCalled = TRUE;
        while (!localeSet)
            Sleep(100);

        WaitForSingleObject(printMutex, INFINITE);
        printf_s("[Thread A] Per-thread locale is enabled.\n");
        printf_s("[Thread A] CRT locale is set to \"%s\"\n",
            setlocale(LC_ALL, NULL));
        printf_s("[Thread A] locale::global is set to \"%s\"\n\n",
            locale().name().c_str());
        ReleaseMutex(printMutex);

        return 1;
    }

    unsigned __stdcall RunThreadB(void *params)
    {
        while (!configThreadLocaleCalled)
            Sleep(100);
        setlocale(LC_ALL, "french");
        localeSet = TRUE;

        WaitForSingleObject(printMutex, INFINITE);
        printf_s("[Thread B] Per-thread locale is NOT enabled.\n");
        printf_s("[Thread B] CRT locale is set to \"%s\"\n",
            setlocale(LC_ALL, NULL));
        printf_s("[Thread B] locale::global is set to \"%s\"\n\n",
            locale().name().c_str());
        ReleaseMutex(printMutex);

        return 1;
    } 复制代码
    [Thread B] Per-thread locale is NOT enabled.
    [Thread B] CRT locale is set to "French_France.1252"
    [Thread B] locale::global is set to "C"

    [Thread A] Per-thread locale is enabled.
    [Thread A] CRT locale is set to "C"
    [Thread A] locale::global is set to "C"

    [Thread main] Per-thread locale is NOT enabled.
    [Thread main] CRT locale is set to "French_France.1252"
    [Thread main] locale::global is set to "C"在此示例中,主线程生成两个子线程。第一个线程(线程 A)通过调用 _configthreadlocale(_ENABLE_PER_THREAD_LOCALE) 启用每线程区域设置。第二个线程(线程 B)与主线程一样,不启用每线程区域设置。然后,线程 B 继续使用标准 C++ 库的 locale::global 方法更改区域设置。

    由于线程 B 没有启用每线程区域设置,线程 B 以及主线程中的 C 运行时库函数开始使用“法国”区域设置。由于线程 A 启用了每线程区域设置,线程 A 中的 C 运行时库函数继续使用“C”区域设置。但是,由于 locale::global 方法会“全局性地”更改区域设置,所有线程中的所有标准 C++ 库对象都开始使用“法国”区域设置。

    复制代码
    // multithread_locale_4.cpp
    // compile with: /EHsc /MD
    #include <clocale>
    #include <cstdio>
    #include <locale>
    #include <process.h>
    #include <windows.h>

    #define NUM_THREADS 2
    using namespace std;

    unsigned __stdcall RunThreadA(void *params);
    unsigned __stdcall RunThreadB(void *params);

    BOOL localeSet = FALSE;
    BOOL configThreadLocaleCalled = FALSE;
    HANDLE printMutex = CreateMutex(NULL, FALSE, NULL);

    int main()
    {
        HANDLE threads[NUM_THREADS];

        unsigned aID;
        threads[0] = (HANDLE)_beginthreadex(
            NULL, 0, RunThreadA, NULL, 0, &aID);

        unsigned bID;
        threads[1] = (HANDLE)_beginthreadex(
            NULL, 0, RunThreadB, NULL, 0, &bID);

        WaitForMultipleObjects(2, threads, TRUE, INFINITE);

        printf_s("[Thread main] Per-thread locale is NOT enabled.\n");
        printf_s("[Thread main] CRT locale is set to \"%s\"\n",
            setlocale(LC_ALL, NULL));
        printf_s("[Thread main] locale::global is set to \"%s\"\n",
            locale().name().c_str());

        CloseHandle(threads[0]);
        CloseHandle(threads[1]);
        CloseHandle(printMutex);

        return 0;
    }

    unsigned __stdcall RunThreadA(void *params)
    {
        _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
        configThreadLocaleCalled = TRUE;
        while (!localeSet)
            Sleep(100);

        WaitForSingleObject(printMutex, INFINITE);
        printf_s("[Thread A] Per-thread locale is enabled.\n");
        printf_s("[Thread A] CRT locale is set to \"%s\"\n",
            setlocale(LC_ALL, NULL));
        printf_s("[Thread A] locale::global is set to \"%s\"\n\n",
            locale().name().c_str());
        ReleaseMutex(printMutex);

        return 1;
    }

    unsigned __stdcall RunThreadB(void *params)
    {
        while (!configThreadLocaleCalled)
            Sleep(100);
        locale::global(locale("french"));
        localeSet = TRUE;

        WaitForSingleObject(printMutex, INFINITE);
        printf_s("[Thread B] Per-thread locale is NOT enabled.\n");
        printf_s("[Thread B] CRT locale is set to \"%s\"\n",
            setlocale(LC_ALL, NULL));
        printf_s("[Thread B] locale::global is set to \"%s\"\n\n",
            locale().name().c_str());
        ReleaseMutex(printMutex);

        return 1;
    } 复制代码
    [Thread B] Per-thread locale is NOT enabled.
    [Thread B] CRT locale is set to "French_France.1252"
    [Thread B] locale::global is set to "French_France.1252"

    [Thread A] Per-thread locale is enabled.
    [Thread A] CRT locale is set to "C"
    [Thread A] locale::global is set to "French_France.1252"

    [Thread main] Per-thread locale is NOT enabled.
    [Thread main] CRT locale is set to "French_France.1252"
    [Thread main] locale::global is set to "French_France.1252"

    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2008/8/11 8:21:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 C/C++编程思想 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/11/28 14:00:15

    本主题贴数3,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    1,488.281ms