C++다 중 스 레 드 와 스 레 드 동기 화 를 어떻게 실현 합 니까?
15513 단어 c + +다 중 스 레 드스 레 드 동기 화
먼저 간단 한 다 중 스 레 드 인 스 턴 스 를 만 들 고 매개 변수 전달 판 이 없 으 며 인 스 턴 스 를 실행 하면 메 인 스 레 드 와 하위 스 레 드 가 불규칙 하 게 작 동 하 는 것 을 발견 할 수 있 습 니 다.
#include <windows.h>
#include <iostream>
using namespace std;
DWORD WINAPI Func(LPVOID lpParamter)
{
for (int x = 0; x < 10; x++)
{
cout << "thread function" << endl;
Sleep(200);
}
return 0;
}
int main(int argc,char * argv[])
{
HANDLE hThread = CreateThread(NULL, 0, Func, NULL, 0, NULL);
CloseHandle(hThread);
for (int x = 0; x < 10; x++)
{
cout << "main thread" << endl;
Sleep(400);
}
system("pause");
return 0;
}
beginthreadex 다 중 스 레 드 구현:이 방법 은 앞의 CreateThread 사용 과 완전히 일치 합 니 다.다만 매개 변수 에 void*를 사용 해 야 합 니 다.이 매개 변 수 는 임 의 유형 으로 강하 게 전환 할 수 있 고 이들 의 실현 효 과 는 완전히 일치 합 니 다.
#include <windows.h>
#include <iostream>
#include <process.h>
using namespace std;
unsigned WINAPI Func(void *arg)
{
for (int x = 0; x < 10; x++)
{
cout << "thread function" << endl;
Sleep(200);
}
return 0;
}
int main(int argc, char * argv[])
{
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, Func, NULL, 0, NULL);
CloseHandle(hThread);
for (int x = 0; x < 10; x++)
{
cout << "main thread" << endl;
Sleep(400);
}
system("pause");
return 0;
}
CreateMutex 상호 배척 잠 금 구현 스 레 드 동기 화:
상호 배척 자 물 쇠 를 사용 하면 단위 시간 내 에 하나의 스 레 드 만 공유 자원 에 대한 독점 을 허용 하여 서로 충돌 하지 않 는 스 레 드 동기 화 를 실현 할 수 있다.
#include <windows.h>
#include <iostream>
using namespace std;
HANDLE hMutex = NULL; //
//
DWORD WINAPI Func(LPVOID lpParamter)
{
for (int x = 0; x < 10; x++)
{
//
WaitForSingleObject(hMutex, INFINITE);
cout << "thread func" << endl;
//
ReleaseMutex(hMutex);
}
return 0;
}
int main(int argc,char * argv[])
{
HANDLE hThread = CreateThread(NULL, 0, Func, NULL, 0, NULL);
hMutex = CreateMutex(NULL, FALSE, "lyshark");
CloseHandle(hThread);
for (int x = 0; x < 10; x++)
{
//
WaitForSingleObject(hMutex, INFINITE);
cout << "main thread" << endl;
//
ReleaseMutex(hMutex);
}
system("pause");
return 0;
}
상호 배척 자 물 쇠 를 통 해 두 개의 스 레 드 함 수 를 동시에 실행 합 니 다.
#include <windows.h>
#include <iostream>
using namespace std;
HANDLE hMutex = NULL; //
#define NUM_THREAD 50
// 1
DWORD WINAPI FuncA(LPVOID lpParamter)
{
for (int x = 0; x < 10; x++)
{
//
WaitForSingleObject(hMutex, INFINITE);
cout << "this is thread func A" << endl;
//
ReleaseMutex(hMutex);
}
return 0;
}
// 2
DWORD WINAPI FuncB(LPVOID lpParamter)
{
for (int x = 0; x < 10; x++)
{
//
WaitForSingleObject(hMutex, INFINITE);
cout << "this is thread func B" << endl;
//
ReleaseMutex(hMutex);
}
return 0;
}
int main(int argc, char * argv[])
{
//
HANDLE tHandle[NUM_THREAD];
// / , signaled
hMutex = CreateMutex(NULL, FALSE, "lyshark");
for (int x = 0; x < NUM_THREAD; x++)
{
if (x % 2)
{
tHandle[x] = CreateThread(NULL, 0, FuncA, NULL, 0, NULL);
}
else
{
tHandle[x] = CreateThread(NULL, 0, FuncB, NULL, 0, NULL);
}
}
//
WaitForMultipleObjects(NUM_THREAD, tHandle, TRUE, INFINITE);
//
CloseHandle(hMutex);
system("pause");
return 0;
}
임계 구역 을 통 해 스 레 드 동기 화 실현:
임계 구역 과 상호 배척 잠 금 의 차이 가 많 지 않 습 니 다.임계 구역 사용 시 CRITICAL 생 성SECTION 임계 구역 대상 은 똑 같이 열쇠 에 해당 합 니 다.스 레 드 함수 의 실행 이 끝나 면 자동 으로 제출 됩 니 다.다음은 임계 구역 함수 의 정의 원형 입 니 다.
//
VOID InitializeCriticalSection(
LPCRITICAL_SECTION lpCriticalSection
);
//
VOID DeleteCriticalSection(
LPCRITICAL_SECTION lpCriticalSection
);
//
VOID EnterCriticalSection(
LPCRITICAL_SECTION lpCriticalSection
);
//
VOID LeaveCriticalSection(
LPCRITICAL_SECTION lpCriticalSection
);
이번에 우 리 는 상호 배척 체 를 적용 하지 않 고 임계 구역 을 사용 하여 스 레 드 동기 화 를 실현 하 였 으 며 결 과 는 상호 배척 체 와 완전히 일치 하여 개인의 취향 을 보 았 다.
#include <windows.h>
#include <iostream>
using namespace std;
CRITICAL_SECTION cs; //
#define NUM_THREAD 50
//
DWORD WINAPI FuncA(LPVOID lpParamter)
{
for (int x = 0; x < 10; x++)
{
//
EnterCriticalSection(&cs);
cout << "this is thread func A" << endl;
//
LeaveCriticalSection(&cs);
}
return 0;
}
int main(int argc, char * argv[])
{
//
HANDLE tHandle[NUM_THREAD];
//
InitializeCriticalSection(&cs);
for (int x = 0; x < NUM_THREAD; x++)
{
tHandle[x] = CreateThread(NULL, 0, FuncA, NULL, 0, NULL);
}
//
WaitForMultipleObjects(NUM_THREAD, tHandle, TRUE, INFINITE);
//
DeleteCriticalSection(&cs);
system("pause");
return 0;
}
Semaphore 는 신 호 를 바탕 으로 라인 동기 화 를 실현 합 니 다.
하나의 신 호 를 정의 하여 신 호 를 0 으로 초기 화하 고 신 호 량 값 이 0 일 때 non-signaled 상태 에 들 어가 0 이상 일 때 signaled 상태 에 들 어 가 는 특성 을 이용 하여 스 레 드 동기 화 를 실현 할 수 있 습 니 다.
#include <windows.h>
#include <iostream>
using namespace std;
static HANDLE SemaphoreOne;
static HANDLE SemaphoreTwo;
// 1
DWORD WINAPI FuncA(LPVOID lpParamter)
{
for (int x = 0; x < 10; x++)
{
// signaled
WaitForSingleObject(SemaphoreOne, INFINITE);
cout << "this is thread func A" << endl;
// non-signaled
ReleaseSemaphore(SemaphoreOne, 1, NULL);
}
return 0;
}
// 2
DWORD WINAPI FuncB(LPVOID lpParamter)
{
for (int x = 0; x < 10; x++)
{
// signaled
WaitForSingleObject(SemaphoreTwo, INFINITE);
cout << "this is thread func B" << endl;
// non-signaled
ReleaseSemaphore(SemaphoreTwo, 1, NULL);
}
return 0;
}
int main(int argc, char * argv[])
{
//
HANDLE hThreadA, hThreadB;
// , 0 non-signaled
SemaphoreOne = CreateSemaphore(NULL, 0, 1, NULL);
// , 1 signaled
SemaphoreTwo = CreateSemaphore(NULL, 1, 1, NULL); //
hThreadA = CreateThread(NULL, 0, FuncA, NULL,0, NULL);
hThreadB = CreateThread(NULL, 0, FuncB, NULL, 0, NULL);
//
WaitForSingleObject(hThreadA, INFINITE);
WaitForSingleObject(hThreadA, INFINITE);
//
CloseHandle(SemaphoreOne);
CloseHandle(SemaphoreTwo);
system("pause");
return 0;
}
위의 코드 는 잠 금 현상 이 발생 하기 쉽다.즉,스 레 드 함수 B 가 실 행 된 후에 A 함 수 는 대기 상태 에 있다.
WaitForSingleObject(semTwo,INFINITE)를 실행 합 니 다.ReleaseSemaphore(semOne,1,NULL)를 받 으 면 스 레 드 함수 가 걸 린 상태 로 들 어 갑 니 다.집행 을 재 개 할 수 있 습 니 다.
#include <windows.h>
#include <stdio.h>
static HANDLE semOne,semTwo;
static int num;
// A
DWORD WINAPI ReadNumber(LPVOID lpParamter)
{
int i;
for (i = 0; i < 5; i++)
{
fputs("Input Number: ", stdout);
// signaled
WaitForSingleObject(semTwo, INFINITE);
scanf("%d", &num);
// non-signaled
ReleaseSemaphore(semOne, 1, NULL);
}
return 0;
}
// B:
DWORD WINAPI Check(LPVOID lpParamter)
{
int sum = 0, i;
for (i = 0; i < 5; i++)
{
// non-signaled
WaitForSingleObject(semOne, INFINITE);
sum += num;
// signaled
ReleaseSemaphore(semTwo, 1, NULL);
}
printf("The Number IS: %d
", sum);
return 0;
}
int main(int argc, char *argv[])
{
HANDLE hThread1, hThread2;
// , 0 non-signaled
semOne = CreateSemaphore(NULL, 0, 1, NULL);
// , 1 signaled
semTwo = CreateSemaphore(NULL, 1, 1, NULL);
hThread1 = CreateThread(NULL, 0, ReadNumber, NULL, 0, NULL);
hThread2 = CreateThread(NULL, 0, Check, NULL, 0, NULL);
//
WaitForSingleObject(hThread1, INFINITE);
WaitForSingleObject(hThread2, INFINITE);
CloseHandle(semOne);
CloseHandle(semTwo);
system("pause");
return 0;
}
CreateEvent 이벤트 대상 동기 화:
이벤트 대상 은 스 레 드 동기 화 를 실현 합 니 다.앞의 임계 구역 과 상호 배척 체 와 크게 다 릅 니 다.이 방법 으로 대상 을 만 들 때 자동 non-signaled 상태 에서 실행 되 는 auto-reset 모드 를 사용 할 수 있 습 니 다.우리 가 필요 한 파 라 메 터 를 설정 할 때 SetEvent(hEvent)를 사용 하여 이벤트 상 태 를 설정 하면 스 레 드 함 수 를 자동 으로 실행 할 수 있 습 니 다.
#include <windows.h>
#include <stdio.h>
#include <process.h>
#define STR_LEN 100
//
static char str[STR_LEN];
//
static HANDLE hEvent;
// A
unsigned WINAPI NumberOfA(void *arg)
{
int cnt = 0;
//
WaitForSingleObject(hEvent, INFINITE);
for (int i = 0; str[i] != 0; i++)
{
if (str[i] == 'A')
cnt++;
}
printf("Num of A: %d
", cnt);
return 0;
}
//
unsigned WINAPI NumberOfOthers(void *arg)
{
int cnt = 0;
//
WaitForSingleObject(hEvent, INFINITE);
for (int i = 0; str[i] != 0; i++)
{
if (str[i] != 'A')
cnt++;
}
printf("Num of others: %d
", cnt - 1);
return 0;
}
int main(int argc, char *argv[])
{
HANDLE hThread1, hThread2;
// non-signaled manual-reset
// , Signaled
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);
// , signaled
SetEvent(hEvent);
WaitForSingleObject(hThread1, INFINITE);
WaitForSingleObject(hThread2, INFINITE);
//non-signaled , signaled
ResetEvent(hEvent);
CloseHandle(hEvent);
system("pause");
return 0;
}
스 레 드 함수 전달 단일 매개 변수:
스 레 드 함수 의 정의 에서 LPVOID 는 하나의 인 자 를 전달 할 수 있 습 니 다.현성 함수 에서 받 고 강하 게 전환(int)(LPVOID)port 만 하면 됩 니 다.
#include <stdio.h>
#include <Windows.h>
//
DWORD WINAPI ScanThread(LPVOID port)
{
//
int Port = (int)(LPVOID)port;
printf("[+] : %5d
", port);
return 1;
}
int main(int argc, char* argv[])
{
HANDLE handle;
for (int port = 0; port < 100; port++)
{
handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ScanThread, (LPVOID)port, 0, 0);
}
WaitForSingleObject(handle, INFINITE);
system("pause");
return 0;
}
스 레 드 함수 전달 다 중 매개 변수:
만약 에 스 레 드 함수 에서 여러 개의 파 라 메 터 를 전달 하려 면 구조 지침 을 전달 해 야 한다.스 레 드 함수 내 부 를 통 해 구조 유형 으로 강하 게 전환 한 후에 수 치 를 얻 었 다.이 사례 는 저 에 게 시간 이 걸 렸 고 인터넷 에서 적당 한 해결 방법 을 찾 지 못 했 거나 찾 은 것 은 모두 비 뚤 어 진 대추 가 마구 돌아 다 니 는 것 이 었 습 니 다.마지막 으로 자신 이 연구 한 결과 주제 가 되 지 않 은 것 을 썼 습 니 다.
주로 스 레 드 함수 에서 호출 된 매개 변 수 는 다음 스 레 드 함수 구조 와 충돌 합 니 다.해결 방법 은 스 레 드 함수 에 들 어 갈 때마다 자신 이 한 부 를 복사 하고 모든 사람 이 자신의 몫 을 사용 해 야 이런 사건 의 발생 을 피 할 수 있 습 니 다.또한 라인 과 함께 사용 하 는 것 이 좋 습 니 다.다음 과 같 을 때 스 레 드 스캐너 의 일부 코드 세 션 입 니 다.
#include <stdio.h>
#include <windows.h>
typedef struct _THREAD_PARAM
{
char *HostAddr; //
DWORD dwStartPort; //
}THREAD_PARAM;
//
DWORD WINAPI ScanThread(LPVOID lpParam)
{
//
THREAD_PARAM ScanParam = { 0 };
// , , , 。
// , 。sb !!
MoveMemory(&ScanParam, lpParam, sizeof(THREAD_PARAM));
printf(" : %-16s --> : %-5d : [Open]
", ScanParam.HostAddr, ScanParam.dwStartPort);
return 0;
}
int main(int argc, char *argv[])
{
THREAD_PARAM ThreadParam = { 0 };
ThreadParam.HostAddr = "192.168.1.10";
for (DWORD port = 1; port < 100; port++)
{
ThreadParam.dwStartPort = port;
HANDLE hThread = CreateThread(NULL, 0, ScanThread, (LPVOID)&ThreadParam, 0, NULL);
WaitForSingleObject(hThread, INFINITE);
}
system("pause");
return 0;
}
출처:https://www.cnblogs.com/lyshark
이상 은 C++다 중 스 레 드 와 스 레 드 동기 화 를 어떻게 실현 하 는 지 에 대한 상세 한 내용 입 니 다.C+다 중 스 레 드 와 스 레 드 동기 화 를 실현 하 는 데 관 한 자 료 는 저희 의 다른 관련 글 에 관심 을 가 져 주 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
hdu 1717 소수 화 점수 2 (수학)소수 화 점수 2 레이 는 수학 시간 에 선생님 의 말씀 을 듣 고 모든 소수 가 점수 로 표시 되 는 형식 이 라 고 말 했다. 그 는 녹 기 시 작 했 고 곧 완성 되 었 다. 그러나 그 는 또 하나의 문 제 를...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.