Linux多線程實現及線程同步函數分析

來源:互聯網
上載者:User

標籤:地址空間   資源   共用資料   thread   linux中   next   ext   std   bsp   

在Linux中,多線程的本質仍是進程,它與進程的區別:

進程:獨立地址空間,擁有PCB

線程:也有PCB,但沒有獨立的地址空間(共用)

線程的特點:

1,線程是輕量級進程,有PCB,建立線程使用的底層函數和進程一樣,都是clone

2,從核心看進程和線程是一樣的,都有各自不同的PCB

3,進程可以蛻變成線程

4,在LINUX中,線程是最小的執行單位,進程是最小的分配資源單位

查看指定線程的LWP號命令:

ps -Lf pid

線程優點:

提高程式並發性

開銷小

資料通訊,共用資料方便

線程缺點:

庫函數 ,不穩定

調試,編寫困難,GDB

對訊號支援不好

 

線程屬性,可以在一開始就設定好分離態,具體在下面的代碼有說明!

線程同步,主要有互斥鎖mutex,讀寫鎖,條件變數,訊號量

 

 

線程建立函數原型:

int pthread_create(    pthread_t *thread,  // 線程ID    const pthread_attr_t *attr, // 線程屬性    void *(*start_routine) (void *), // 線程主函數    void *arg// 主函數參數);

  粘上基本建立執行緒模式:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <unistd.h>#include <pthread.h>//函數回調void *mythread(void *args){printf("child thread id==[%ld]\n", pthread_self());}int main(){pthread_t thread;//建立一個線程int ret = pthread_create(&thread, NULL, mythread, NULL);if(ret!=0){printf("pthread_create error, [%s]\n", strerror(ret)); return -1;}printf("main thread id==[%ld]\n", pthread_self());sleep(1);}

  線程屬性,在建立時分離代碼:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <unistd.h>#include <pthread.h>void *mythread(void *args){printf("child thread id==[%ld]\n", pthread_self());}int main(){pthread_t thread;//線程屬性pthread_attr_t attr;//線程屬性初始化pthread_attr_init(&attr);//設定線程到分離屬性pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);//建立一個線程int ret = pthread_create(&thread, &attr, mythread, NULL);if(ret!=0){printf("pthread_create error, [%s]\n", strerror(ret)); return -1;}printf("main thread id==[%ld]\n", pthread_self());sleep(1);ret = pthread_join(thread, NULL);if(ret!=0){printf("pthread_join error, [%s]\n", strerror(ret));}//釋放線程屬性pthread_attr_destroy(&attr);return 0;}

  互斥鎖實現代碼:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <unistd.h>#include <pthread.h>#include <time.h>//定義一把鎖pthread_mutex_t mutex;void *mythread1(void *args){while(1){//加鎖pthread_mutex_lock(&mutex);pthread_mutex_lock(&mutex);printf("hello ");sleep(rand()%3);printf("world\n");//解鎖pthread_mutex_unlock(&mutex);sleep(rand()%3);}pthread_exit(NULL);}void *mythread2(void *args){while(1){//加鎖pthread_mutex_lock(&mutex);printf("HELLO ");sleep(rand()%3);printf("WORLD\n");//解鎖pthread_mutex_unlock(&mutex);sleep(rand()%3);}pthread_exit(NULL);}int main(){int ret;pthread_t thread1;pthread_t thread2;//隨機數種子srand(time(NULL));//互斥鎖初始化pthread_mutex_init(&mutex, NULL);ret = pthread_create(&thread1, NULL, mythread1, NULL);if(ret!=0){printf("pthread_create error, [%s]\n", strerror(ret));return -1;}ret = pthread_create(&thread2, NULL, mythread2, NULL);if(ret!=0){printf("pthread_create error, [%s]\n", strerror(ret));return -1;}//等待線程結束pthread_join(thread1, NULL);pthread_join(thread2, NULL);//釋放互斥鎖pthread_mutex_destroy(&mutex);return 0;}

  讀寫鎖代碼:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <unistd.h>#include <pthread.h>int number = 0;//定義一把讀寫鎖pthread_rwlock_t rwlock;void *fun_write(void *args){int i = *(int *)args;int n;while(1){//加寫鎖pthread_rwlock_wrlock(&rwlock);n = number;n++;//sleep(rand()%3);number = n;printf("W->[%d]:[%d]\n", i, number);//解寫鎖pthread_rwlock_unlock(&rwlock);sleep(rand()%3);}pthread_exit(NULL);}void *fun_read(void *args){int i = *(int *)args;while(1){//加讀鎖pthread_rwlock_rdlock(&rwlock);printf("R->[%d]:[%d]\n", i, number);//解鎖pthread_rwlock_unlock(&rwlock);sleep(rand()%3);}pthread_exit(NULL);}int main(){int i;int ret;int n = 8;int arr[8];pthread_t thread[8];//讀寫鎖初始化pthread_rwlock_init(&rwlock, NULL);//建立3個寫線程for(i=0; i<3; i++){arr[i] = i;ret = pthread_create(&thread[i], NULL, fun_write, (void *)&arr[i]);if(ret!=0){printf("pthread_create error, [%s]\n", strerror(ret));return -1;}}//建立5個讀線程for(i=3; i<n; i++){arr[i] = i;ret = pthread_create(&thread[i], NULL, fun_read, (void *)&arr[i]);if(ret!=0){printf("pthread_create error, [%s]\n", strerror(ret));return -1;}}for(i=0; i<n; i++){//回收子線程pthread_join(thread[i], NULL);}//釋放讀寫鎖資源pthread_rwlock_destroy(&rwlock);return 0;}

  cond條件變數代碼:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <unistd.h>#include <pthread.h>typedef struct node{int data;struct node *next;}NODE;//鏈表前端節點指標NODE *head = NULL;//互斥鎖pthread_mutex_t mutex;//條件變數pthread_cond_t cond;//生產者線程處理函數void *producer(void *args){NODE *pNode = NULL;while(1){pNode = (NODE *)malloc(sizeof(NODE));if(pNode==NULL){perror("malloc error\n");exit(1);}pNode->data = rand()%1000;//lock共用資源 pthread_mutex_lock(&mutex);pNode->next = head;head=pNode;printf("P:[%d]\n", head->data);//對共用資源解鎖pthread_mutex_unlock(&mutex);//使用條件變數解除對線程到阻塞pthread_cond_signal(&cond);sleep(rand()%3);}}//消費者線程處理函數void *consumer(void *args){NODE *pNode = NULL;while(1){//lock共用資源 pthread_mutex_lock(&mutex);if(head==NULL){//條件不滿足阻塞等待head不為空白pthread_cond_wait(&cond, &mutex);}printf("C:[%d]\n", head->data);pNode = head;head = head->next;//對共用資源解鎖pthread_mutex_unlock(&mutex);free(pNode);pNode = NULL;sleep(rand()%3);}}int main(int argc, char *argv[]){int ret;pthread_t thread1;pthread_t thread2;pthread_mutex_t mutex;pthread_cond_t cond;//初始化互斥鎖pthread_mutex_init(&mutex, NULL);//初始化條件變數pthread_cond_init(&cond, NULL);//建立生產者線程ret = pthread_create(&thread1, NULL, producer, NULL);if(ret!=0){printf("pthread_create error, [%s]\n", strerror(ret));return -1;}//建立消費者線程ret = pthread_create(&thread2, NULL, consumer, NULL);if(ret!=0){printf("pthread_create error, [%s]\n", strerror(ret));return -1;}//主線程回收子線程pthread_join(thread1, NULL);pthread_join(thread2, NULL);//釋放鎖資源pthread_mutex_destroy(&mutex);//釋放條件變數資源pthread_cond_destroy(&cond);return 0;}

  訊號量,經典消費者生產者模型:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <unistd.h>#include <pthread.h>#include <semaphore.h>typedef struct node{int data;struct node *next;}NODE;//鏈表前端節點指標NODE *head = NULL;sem_t sem_consumer;sem_t sem_producer;//生產者線程處理函數void *producer(void *args){NODE *pNode = NULL;while(1){pNode = (NODE *)malloc(sizeof(NODE));if(pNode==NULL){perror("malloc error\n");exit(1);}pNode->data = rand()%1000;//sem_producer--, 若為0則阻塞sem_wait(&sem_producer);pNode->next = head;head=pNode;printf("P:[%d]\n", head->data);//sem_consumer++sem_post(&sem_consumer);sleep(rand()%3);}}//消費者線程處理函數void *consumer(void *args){NODE *pNode = NULL;while(1){//sem_consumer--, 若為0則阻塞sem_wait(&sem_consumer);printf("C:[%d]\n", head->data);pNode = head;head = head->next;//sem_producer++sem_post(&sem_producer);free(pNode);pNode = NULL;sleep(rand()%3);}}int main(int argc, char *argv[]){int ret;pthread_t thread1;pthread_t thread2;//訊號量初始化sem_init(&sem_producer, 0, 5);sem_init(&sem_consumer, 0, 0);//建立生產者線程ret = pthread_create(&thread1, NULL, producer, NULL);if(ret!=0){printf("pthread_create error, [%s]\n", strerror(ret));return -1;}//建立消費者線程ret = pthread_create(&thread2, NULL, consumer, NULL);if(ret!=0){printf("pthread_create error, [%s]\n", strerror(ret));return -1;}//主線程回收子線程pthread_join(thread1, NULL);pthread_join(thread2, NULL);//釋放訊號量資源sem_destroy(&sem_producer);sem_destroy(&sem_consumer);return 0;}

  

Linux多線程實現及線程同步函數分析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.