一、多線程基本概念
1. 線程的基本概念
① 線程就是輕量級的進程
②線程和創建他的進程共享代碼段、數據段
③線程擁有自己的棧
2. 在實際應用中,多個線程往往會訪問同一數據或資源,為避免線程之間相互影響,需要引入互斥機制,而互斥鎖(mutex)是互斥機制中的一種
3. 簡單實例
#include <stdio.h> #include <pthread.h> pthread_t work1Id; pthread_t work2Id; int work1Ret = 1; int work2Ret = 2; pthread_mutex_t mutex; int number = 0; void* Work1(void* args) { int i = 0; printf("I am work%d\n", *((int*)args)); for(i = 0; i < 10; i++) { pthread_mutex_lock(&mutex); number++; pthread_mutex_unlock(&mutex); printf("I am work%d, number = %d\n", *((int*)args), number); sleep(1); } return &work1Ret; } void* Work2(void* args) { int i = 0; printf("I am work%d\n", *((int*)args)); for(i = 0; i < 10; i++) { pthread_mutex_lock(&mutex); number++; pthread_mutex_unlock(&mutex); printf("I am work%d, number = %d\n", *((int*)args), number); sleep(1); } return &work2Ret; } int main() { int args1 = 1; int args2 = 2; void* work1Ret = NULL; void* work2Ret = NULL; pthread_mutex_init(&mutex, NULL); pthread_create(&work1Id, NULL, Work1, &args1); pthread_create(&work2Id, NULL, Work2, &args2); pthread_join(work1Id, &work1Ret); if(work1Ret != NULL) { printf("work1Ret = %d\n", *((int*)work1Ret)); } pthread_join(work2Id, &work2Ret); if(work2Ret != NULL) { printf("work2Ret = %d\n", *((int*)work2Ret)); } return 0; }
二、線程同步
1. 多個線程按照規定的順序來執行,即為線程同步。
2. 條件變量
①初始化
pthread_cond_t cond_ready = PTHREAD_COND_INITIALIZER;
②等待條件成熟
pthread_wait(&cond_ready, &mutex); //會對mutex先進行解鎖操作
③設置成熟條件
pthread_cond_signal(&cond_ready)
3. 簡單實例
#include <stdio.h> #include <pthread.h> pthread_t work1Id; pthread_t work2Id; int work1Ret = 1; int work2Ret = 2; pthread_cond_t cond_ready = PTHREAD_COND_INITIALIZER; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; int number = 0; void* Work1(void* args) { int i = 0; printf("I am work%d\n", *((int*)args)); for(i = 0; i < 10; i++) { pthread_mutex_lock(&mutex); number++; if(number >= 10) { printf("I am work%d, Finish\n", *((int*)args)); pthread_cond_signal(&cond_ready); } pthread_mutex_unlock(&mutex); printf("I am work%d, number = %d\n", *((int*)args), number); sleep(1); } return &work1Ret; } void* Work2(void* args) { printf("I am work%d\n", *((int*)args)); pthread_mutex_lock(&mutex); if(number <= 10) { pthread_cond_wait(&cond_ready, &mutex); printf("I am work%d, number = %d\n", *((int*)args), number); } return &work2Ret; } int main() { int args1 = 1; int args2 = 2; void* work1Ret = NULL; void* work2Ret = NULL; pthread_create(&work1Id, NULL, Work1, &args1); pthread_create(&work2Id, NULL, Work2, &args2); pthread_join(work1Id, &work1Ret); if(work1Ret != NULL) { printf("work1Ret = %d\n", *((int*)work1Ret)); } pthread_join(work2Id, &work2Ret); if(work2Ret != NULL) { printf("work2Ret = %d\n", *((int*)work2Ret)); } return 0; }