閱讀146 返回首頁    go 技術社區[雲棲]


Linux 線程掛起與喚醒功能 實例

pthread_cond_wait

多線程的條件變量

條件變量是利用線程間共享的全局變量進行同步的一種機製,主要包括兩個動作:一個線程等待"條件變量的條件成立"而掛起;另一個線程使"條件成立"(給出條件成立信號)。為了防止競爭,條件變量的使用總是和一個互斥鎖結合在一起。

創建和注銷

條件變量和互斥鎖一樣,都有靜態動態兩種創建方式,靜態方式使用PTHREAD_COND_INITIALIZER常量,如下:
pthread_cond_t cond=PTHREAD_COND_INITIALIZER
動態方式調用pthread_cond_init()函數,API定義如下:
int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr)
盡管POSIX標準中為條件變量定義了屬性,但在LinuxThreads中沒有實現,因此cond_attr值通常為NULL,且被忽略。
等待和激發

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)

在調用pthread_cond_wait()前必須由本線程加鎖(pthread_mutex_lock()),而在更新條件等待隊列以前,mutex保持鎖定狀態,並在線程掛起進入等待前解鎖。在條件滿足從而離開pthread_cond_wait()之前,mutex將被重新加鎖,以與進入pthread_cond_wait()前的加鎖動作對應。

pthread_cond_signal()激活一個等待該條件的線程,存在多個等待線程時按入隊順序激活其中一個

/*
*主線程創建子線程(當前子線程為stop停止狀態),5秒後主線程喚醒子線程,
*10秒後主線程掛起子線程。15秒後主線程再次喚醒子線程,20秒後主線程執行完畢,
*等待子線程退出。
*/
#include <stdio.h>
#include <string.h>
#include <pthread.h>

#define	RUN 	1
#define STOP	0

pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

int status = STOP;

void *thread_function(void)
{
	static int i = 0;
	while(1)
	{
		pthread_mutex_lock(&mut);
		while(!status)
		{
			pthread_cond_wait(&cond, &mut);
		}
		pthread_mutex_unlock(&mut);
		printf("child pthread %d\n", i++);
		if (i == 20)
		{
			break;
		}
		sleep(1);
	}
}

void thread_resume()
{
	if (status == STOP)
	{
		pthread_mutex_lock(&mut);
		status = RUN;
		pthread_cond_signal(&cond);
		printf("pthread run!\n");
		pthread_mutex_unlock(&mut);
	}
	else
	{
		printf("pthread run already\n");
	}
}

void thread_pause()
{
	if (status == RUN)
	{
		pthread_mutex_lock(&mut);
		status = STOP;
		printf("thread stop!\n");
		pthread_mutex_unlock(&mut);
	}
	else
	{
		printf("pthread pause already\n");
	}
}

int main()
{
	int err;
	static int i = 0;
	pthread_t child_thread;
	
	if (pthread_mutex_init(&mut, NULL) != 0)
	{
		printf("mutex init error\n");
	}
	if (pthread_cond_init(&cond, NULL) != 0)
	{
		printf("cond init error\n");
	}
	
	err = pthread_create(&child_thread,NULL,(void *)thread_function,NULL);
	if (err != 0)
	{
		printf("can't create thread:%s\n", strerror(err));
	}
	
	while(1)
	{
		printf("father pthread %d\n", i++);
		sleep(1);
		if (i == 5)
		{
			thread_resume();
		}
		if (i == 10)
		{
			thread_pause();
		}
		if (i == 15)
		{
			thread_resume();
		}
		if (i == 20)
		{
			break;
		}
	}
	if (0 == pthread_join(child_thread, NULL))
	{
		printf("child thread is over\n");
	}
	
	return 0;
}



最後更新:2017-04-03 12:56:08

  上一篇:go 二叉樹的鏡像-jobdu-1521
  下一篇:go CFS 調度器