Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Både C Runtime-biblioteket och C++-standardbiblioteket har stöd för att ändra programmets nationella inställningar. I det här avsnittet beskrivs problem som uppstår när du använder lokaliseringsfunktionerna i båda biblioteken i ett flertrådat program.
Anmärkningar
Med C Runtime-biblioteket kan du skapa flertrådade program med hjälp av _beginthread funktionerna och _beginthreadex . Det här avsnittet beskriver endast flertrådade program som skapats med hjälp av dessa funktioner. Mer information finns i _beginthread, _beginthreadex.
Om du vill ändra nationella inställningar med hjälp av C Runtime-biblioteket använder du funktionen setlocale . I tidigare versioner av Visual C++skulle den här funktionen alltid ändra nationella inställningar i hela programmet. Det finns nu stöd för att ange nationella inställningar per tråd. Detta görs med hjälp av funktionen _configthreadlocale . Om du vill ange att setlocale endast ska ändra språkvarianten i den aktuella tråden anropar du _configthreadlocale(_ENABLE_PER_THREAD_LOCALE) den tråden. Anrop _configthreadlocale(_DISABLE_PER_THREAD_LOCALE) gör att tråden använder det globala språket, och alla anrop till setlocale i den tråden ändrar språkvarianten i alla trådar som inte uttryckligen har aktiverat språkvarianten per tråd.
Om du vill ändra språkvarianten med hjälp av C++-körningsbiblioteket använder du språkklassen. Genom att anropa metoden locale::global ändrar du nationella inställningar i varje tråd som inte uttryckligen har aktiverat nationella inställningar per tråd. Om du vill ändra språkvarianten i en enda tråd eller del av ett program skapar du bara en instans av ett locale objekt i den tråden eller delen av koden.
Anmärkning
Anrop av locale::global ändrar lokal för både C++ Standardbiblioteket och C Runtime-biblioteket. Om du anropar setlocale ändras dock bara språkvarianten för C Runtime-biblioteket. C++-standardbiblioteket påverkas inte.
I följande exempel visas hur du använder funktionen setlocale , språkvariantklassen och funktionen _configthreadlocale för att ändra språkvarianten för ett program i flera olika scenarier.
Exempel: Ändra lokal inställning med per-trådslokalisering aktiverad
I det här exemplet skapar huvudtråden två underordnade trådar. Den första tråden, Tråd A, aktiverar lokalinställning per tråd genom att anropa _configthreadlocale(_ENABLE_PER_THREAD_LOCALE). Den andra tråden, Tråd B, samt huvudtråden, aktiverar inte nationella inställningar per tråd. Tråd A fortsätter sedan med att ändra nationella inställningar med hjälp av funktionen setlocale i C Runtime-biblioteket.
Eftersom tråd A har språkvarianten per tråd aktiverad börjar bara C Runtime Library-funktionerna i Tråd A med språkvarianten "franska". C Runtime-biblioteksfunktionerna i tråd B och i huvudtråden fortsätter att använda språkvarianten "C". Eftersom setlocale inte påverkar språkvarianten för C++-standardbiblioteket fortsätter alla C++ standardbiblioteksobjekt att använda språkvarianten "C".
// 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"
Exempel: Ändra globala språkinställningar med språkinställning per tråd aktiverad.
I det här exemplet skapar huvudtråden två underordnade trådar. Den första tråden, Tråd A, aktiverar lokalinställning per tråd genom att anropa _configthreadlocale(_ENABLE_PER_THREAD_LOCALE). Den andra tråden, Tråd B, samt huvudtråden, aktiverar inte nationella inställningar per tråd. Tråd A fortsätter sedan med att ändra den lokala inställningen med hjälp av locale::global-metoden för C++-standardbiblioteket.
Eftersom tråd A har språkvarianten per tråd aktiverad börjar bara C Runtime Library-funktionerna i Tråd A med språkvarianten "franska". C Runtime-biblioteksfunktionerna i tråd B och i huvudtråden fortsätter att använda språkvarianten "C". Men eftersom metoden locale::global ändrar språkvarianten "globalt" börjar alla C++ Standard Library-objekt i alla trådar använda språkspråket "franska".
// 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"
Exempel: Ändra nationella inställningar utan att språkvarianten per tråd har aktiverats
I det här exemplet skapar huvudtråden två underordnade trådar. Den första tråden, Tråd A, aktiverar lokalinställning per tråd genom att anropa _configthreadlocale(_ENABLE_PER_THREAD_LOCALE). Den andra tråden, Tråd B, samt huvudtråden, aktiverar inte nationella inställningar per tråd. Tråd B fortsätter sedan med att ändra nationella inställningar med hjälp av funktionen setlocale i C Runtime-biblioteket.
Eftersom tråd B inte har språkvarianten per tråd aktiverad fungerar C Runtime-biblioteket i tråd B och i huvudtråden börjar använda språkvarianten "franska". C Runtime-biblioteksfunktionerna i Tråd A fortsätter att använda språkvarianten "C" eftersom tråd A har språkvarianten per tråd aktiverad. Eftersom setlocale inte påverkar språkvarianten för C++-standardbiblioteket fortsätter alla C++ standardbiblioteksobjekt att använda språkvarianten "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"
Exempel: Ändra globala nationella inställningar utan att språkvarianten per tråd har aktiverats
I det här exemplet skapar huvudtråden två underordnade trådar. Den första tråden, Tråd A, aktiverar lokalinställning per tråd genom att anropa _configthreadlocale(_ENABLE_PER_THREAD_LOCALE). Den andra tråden, Tråd B, samt huvudtråden, aktiverar inte nationella inställningar per tråd. Tråd B fortsätter sedan med att ändra locale med hjälp av locale::global-metoden i C++-standardbiblioteket.
Eftersom tråd B inte har språkvarianten per tråd aktiverad fungerar C Runtime-biblioteket i tråd B och i huvudtråden börjar använda språkvarianten "franska". C Runtime-biblioteksfunktionerna i Tråd A fortsätter att använda språkvarianten "C" eftersom tråd A har språkvarianten per tråd aktiverad. Men eftersom metoden locale::global ändrar språkvarianten "globalt" börjar alla C++ Standard Library-objekt i alla trådar använda språkspråket "franska".
// 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"
Se även
Stöd för multitrådning för äldre kod (Visual C++)
_beginthread, _beginthreadex
_configthreadlocale
setlocale
Internationalisering
regionala inställningar
<clocale>
<Locale>
lokal klass