条件变量和互斥锁的联系

互斥锁:(也称之为互斥量)。

每个线程在对资源操作前都尝试先加锁,成功加锁才能操作,操作结束解锁。

但通过“锁”就将资源的访问变成互斥操作,而后与时间有关的错误也不会再产生了

但,应注意:同一时刻,只能有一个线程持有该锁。

当A线程对某个全局变量加锁访问,B在访问前尝试加锁,拿不到锁,B阻塞。C线程不去加锁,而直接访问该全局变量,依然能够访问,但会出现数据混乱。

条件变量(Condition Variable)是一种同步机制,用于协调线程之间的操作。它通常与互斥锁(Mutex)结合使用,以实现线程间的协作。

条件变量和互斥锁的联系_第1张图片

条件变量允许线程在等待某些特定条件时被阻塞,直到其他线程在满足这些条件时通知它们。在等待条件期间,线程可以释放互斥锁,从而允许其他线程访问共享资源,同时避免竞争条件。(这是为什么互斥锁和条件变量可以结合的关键条件)

当某个线程满足条件时,它可以使用条件变量通知正在等待的线程。在接收到通知后,线程可以重新获取互斥锁,并继续执行。

条件变量在编写多线程应用程序时非常有用,因为它们可以帮助避免死锁,并允许线程在满足特定条件时才进行操作,从而提高应用程序的效率。

#include 
#include 
#include 
#include 
#include 

static char g_buf[1000];
static pthread_mutex_t g_tMutex  = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t  g_tConVar = PTHREAD_COND_INITIALIZER;

static void *my_thread_func (void *data)
{
	while (1)
	{
		/* 等待通知 */
		pthread_mutex_lock(&g_tMutex);/*第二步 加锁*/
		printf("wait\n");
		pthread_cond_wait(&g_tConVar, &g_tMutex);/*第三步:等待并解锁 第七步:唤醒并加锁 */

		/* 打印 */
		printf("recv: %s\n", g_buf);  
		pthread_mutex_unlock(&g_tMutex);  /*第八步  解锁*/
        printf("recv:%s\n", g_buf);
	}

	return NULL;
}


int main(int argc, char **argv)
{
	pthread_t tid;
	int ret;
	char buf[1000];
	
	/* 1. 创建"接收线程" */
	ret = pthread_create(&tid, NULL, my_thread_func, NULL);  /*第一步:由于程序执行的先后性,先进入该线程 */
	if (ret)
	{
		printf("pthread_create err!\n");
		return -1;
	}


	/* 2. 主线程读取标准输入, 发给"接收线程" */
	while (1)
	{
		fgets(buf, 1000, stdin);
		pthread_mutex_lock(&g_tMutex);/*第四步:因为上面解锁了 所以我这里可以重新加锁*/
		printf("lock\n");
		memcpy(g_buf, buf, 1000);
		pthread_cond_signal(&g_tConVar); /* 通知接收线程 */ /*第五步:唤醒条件变量*/
	    printf("unlock\n");
		pthread_mutex_unlock(&g_tMutex);/*第六步 紧接着 解锁*/
	}
	return 0;
}

编译:

gcc pthread5.c -o pthread5 -lpthread

结果:

互斥锁(mutex)-CSDN博客

条件变量详细解说-CSDN博客

你可能感兴趣的:(linux,c语言)