天天看點

pthread_cond_broadcast與pthread_cond_signal的差別——linuxc

轉載:https://blog.csdn.net/afootball/article/details/107937516

pthread_cond_signal——喚醒睡眠的線程,一次隻能喚醒一個線程

pthread_cond_broadcast——喚醒睡眠的線程,一次喚醒所有睡眠的線程

了解:

  1. pthread_cond_wait函數是解鎖等待(即:函數被調用後,互斥鎖是出于解鎖狀态的。)這也是為什麼demon1中,兩個線程都加鎖了,但是進入睡眠的列印資訊都列印出來了,因為線程1調用該函數後,将鎖解開了。
  2. pthread_cond_wait函數是解鎖等待,也就是說,在該函數調用前必須要加鎖,否則就談不上解鎖。那麼pthread_cond_signal函數的調用過程中是否必須加鎖呢???
  3. 以下示例的用法,未加任何判斷條件的wait,阻塞,可以用作是線程間的通信,有點象Qt中的信号與槽的操作。
  4. pthread_cond_signal函數每次喚醒的線程未知,故此函數使用時,是針對一個生産者對應一個消費者的問題。

demon1——pthread_cond_signal

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

static pthread_t thread1;
static pthread_t thread2;

//靜态初始化
static pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond=PTHREAD_COND_INITIALIZER;

void *function1()

{
	while(1)
	{
		pthread_mutex_lock(&lock);
		printf("=====  線程1進入睡眠        ====\n");
		pthread_cond_wait(&cond,&lock);
		printf("====  線程1    喚醒    ====\n");
		pthread_mutex_unlock(&lock);
	}
}

void *function2()

{
	while(1)
	{
		pthread_mutex_lock(&lock);
		printf("=====  線程2進入睡眠        ====\n");
		pthread_cond_wait(&cond,&lock);
		printf("====  線程2    喚醒    ====\n");
		pthread_mutex_unlock(&lock);
	}
}


int main()
{
	int i=0;
	if(-1==pthread_create(&thread1,NULL,function1,NULL))
	{
		printf("thread_create1 fail!\n");
		pthread_detach(thread1);
	}

	if(-1==pthread_create(&thread2,NULL,function2,NULL))
	{
		printf("thread_create fail!\n");
		pthread_detach(thread1);
	}

	while(1)
	{
		sleep(2);
		i++;
		printf("\n 第%d次喚醒\n",i);
		pthread_mutex_lock(&lock);
		if(-1==pthread_cond_signal(&cond))
		{
			printf("pthread_cond_broadcast error!\n");
		}
		pthread_mutex_unlock(&lock);
	}
	return 0;
}
           

運作結果: 

pthread_cond_broadcast與pthread_cond_signal的差別——linuxc

demon2——pthread_cond_broadcast

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

static pthread_t thread1;
static pthread_t thread2;

//靜态初始化
static pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond=PTHREAD_COND_INITIALIZER;

void *function1()

{
	while(1)
	{
		pthread_mutex_lock(&lock);
		printf("=====  線程1進入睡眠        ====\n");
		pthread_cond_wait(&cond,&lock);
		printf("====  線程1    喚醒    ====\n");
		pthread_mutex_unlock(&lock);
	}
}

void *function2()

{
	while(1)
	{
		pthread_mutex_lock(&lock);
		printf("=====  線程2進入睡眠        ====\n");
		pthread_cond_wait(&cond,&lock);
		printf("====  線程2    喚醒    ====\n");
		pthread_mutex_unlock(&lock);
	}
}


int main()
{
	int i=0;
	if(-1==pthread_create(&thread1,NULL,function1,NULL))
	{
		printf("thread_create1 fail!\n");
		pthread_detach(thread1);
	}

	if(-1==pthread_create(&thread2,NULL,function2,NULL))
	{
		printf("thread_create fail!\n");
		pthread_detach(thread1);
	}

	while(1)
	{
		sleep(2);
		i++;
		printf("\n 第%d次喚醒\n",i);
		pthread_mutex_lock(&lock);
		if(-1==pthread_cond_broadcast(&cond))
		{
			printf("pthread_cond_broadcast error!\n");
		}
		pthread_mutex_unlock(&lock);
	}
	return 0;
}
           

運作結果:

pthread_cond_broadcast與pthread_cond_signal的差別——linuxc

 對比運作結果,清楚的可以發現pthread_cond_broadcast可以喚醒所有睡眠的線程

繼續閱讀