UNIX 網絡編程之線程

 概述:

   實現併發服務器一般都是父進程accept一個連接,然後fork一個子進程,該子進程處理與該連接對端的客戶之間的通信。但是fork是昂貴,耗資源和時間。而線程是輕量級線程,它的創建比進程的創建塊10-100倍。在同一進程內除了共享全局變量外還共享:

 大多數數據;進程指令; 打開的文件; 信號處理函數信號處置; 當前工作目錄;用戶ID和組ID

不過每個線程有各自的資源:‘

 線程ID; 寄存器集合了棧了errno; 信號掩碼; 優先級

基本線程函數:創建和終止

  pthread_create函數

  #include <pthread.h>

  int pthread_create(pthread_t *tid, const pthread_attr_t *attr, void *(*func)(void *), void *arg);

 一個進程的每個線程都由一個線程ID標識。每個線程有很多屬性,比如優先級大小,初始棧大小,是否應該成爲一個守護線程等等


  pthread_join函數

 #include <pthread.h>

  int pthread_join(pthread_t *tid, void **status);

  該函數類似與waitpid


  pthread_self函數

   #include <pthread.h>
  int pthread_self(void);

  每個線程使用pthread_self獲得自身的線程ID


 pthread_detach函數

 #include <pthread.h>

  int pthread_detach(pthread_t tid);

  一個線程或者是可匯合的,或者是脫離的。當一個可匯合的線程終止時,它的線程ID和退出狀態將留存到另一個線程對它調用pthread_join。脫離的線程像守護線程,當他們終止時,所有相關資源都被釋放.


 pthread_exit函數

  

 #include <pthread.h>

  int pthread_exit(void *status);

結束一個線程


互斥鎖的使用

多線程程序的經典問題:多個線程同時修改一個共享變量(如全局變量)

#include <pthread.h>
#include <stdio.h>

int counter;
void *doit(void*);

int main(int argc, char **argv)
{
	pthread_t tidA, tidB;

	pthread_create(&tidA, NULL, &doit, NULL);
	pthread_create(&tidB, NULL, &doit, NULL);

	pthread_join(tidA, NULL);
	pthread_join(tidB, NULL);
	return 0;
}

void *doit(void * arg)
{
	int i, val;
	for(i=0; i<10; i++)
	{
		val = counter;
		printf("counter is %d\n", val+1);
		counter = val+1;
	}
	return NULL;
}
上面程序的運行結果並不是我們想要的結果,因爲線程的運行是併發運行的,也就是說counter值的修改的結果是不定的,以下爲運行結果


所以我們應該引入同步機制,首先使用互斥量實現

#include <pthread.h>
#include <stdio.h>

int counter;
pthread_mutex_t counter_mutex;

void *doit(void*);

int main(int argc, char **argv)
{
	pthread_t tidA, tidB;

	pthread_create(&tidA, NULL, &doit, NULL);
	pthread_create(&tidB, NULL, &doit, NULL);

	pthread_join(tidA, NULL);
	pthread_join(tidB, NULL);
	return 0;
}

void *doit(void * arg)
{
	
	int i, val;
	for(i=0; i<10; i++)
	{
		pthread_mutex_lock(&counter_mutex);
		val = counter;
		printf("counter is %d\n", val+1);
		counter = val+1;
		pthread_mutex_unlock(&counter_mutex);
	}
	return NULL;
}

使用在對counter值進行修改之前進行上鎖操作,修改之後,進行解鎖操作


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章