多线程操作

windows c++中的sleep(3000)是3000毫秒,就是3秒

而linux中sleep(3000)是3000秒。


实现多线程程序,一个线程打印3的倍数,另一个线程打印剩下数字

应该要用条件变量实现,条件变量一定要和互斥量连用

信号量与Mutex最大的不同是,Mutex只能被acquire它的线程release, 可semaphore可以被不同的线程release

如果是本线程对互斥量加锁,则只能由本线程解锁

pthread_cond_wait ()和pthread_cond_timedwait()都被实现为取消点,因此,在该处等待的线程将立即重新运行,在重新锁定mutex后离开 pthread_cond_wait(),然后执行取消动作。也就是说如果pthread_cond_wait()被取消,mutex是保持锁定状态的,因而需要定义退出回调函数来为其解锁。
pthread_cond_wait实际上可以看作是以下几个动作的合体:
解锁线程锁;
等待条件为true;
加锁线程锁;

使用形式:
// 线程一代码
pthread_mutex_lock(&mutex);
if (条件满足)
pthread_cond_signal(&cond);//即使在线程1中发送了cond,线程二收到了cond,但是此时线程二要堵塞到pthread_cond_wait内部的加锁,也就是说只有线程一unlock mutex之后,线程二才能在pthread_cond_wait函数内部加锁后继续运行
pthread_mutex_unlock(&mutex);

//也就只有在这个模块之后,线程二的代码才可能在满足条件的情况下运行

// 线程二代码
pthread_mutex_lock(&mutex);
while (条件不满足)
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
/*线程二中为什么使用while呢?因为在pthread_cond_signal和pthread_cond_wait返回之间,有时间差,假设在这个时间差内,条件改变了,显然需要重新检查条件。也就是说在pthread_cond_wait被唤醒的时候可能该条件已经不成立。*/

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

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; /*初始化互斥锁*/
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;  //初始化条件变量 
pthread_cond_t cond1 = PTHREAD_COND_INITIALIZER;  //初始化条件变量 

const int N = 100;
void *thread1(void *);
void *thread2(void *);

int i=1;
int main()
{
	
	pthread_t t_a;
	pthread_t t_b;
	pthread_create(&t_a,NULL,thread1,(void *)NULL);//创建进程t_a
	pthread_create(&t_b,NULL,thread2,(void *)NULL); //创建进程t_b
	pthread_join(t_b, NULL);//等待进程t_b结束
	pthread_mutex_destroy(&mutex);
	pthread_cond_destroy(&cond);
	return 0;
}

void *thread1(void *junk)
{
	for(;i<=N;)
	{
		pthread_mutex_lock(&mutex);//
		while(i%3==0)
		{
			pthread_cond_signal(&cond);//通知线程2打印
			pthread_cond_wait(&cond1,&mutex);//当收到cond1时才取消堵塞
		}
	//线程1主要打印非3的倍数的数字
		
		printf("thead1:%d\n",i);
		++i;
		
		pthread_mutex_unlock(&mutex);//*解锁互斥量*/

		
	}

}

void *thread2(void *junk)
{
	while(i<N)
	{
		pthread_mutex_lock(&mutex);

		while(i%3!=0)
		{
			pthread_cond_signal(&cond1);
			pthread_cond_wait(&cond,&mutex);/*等待*/
		}
		printf("thread2:%d\n",i);
		++i;
		pthread_mutex_unlock(&mutex);
		
	}

}

g++ -lpthread cond.cpp -o mutex


在boost或者c#中还有一种更为简单直接的加锁方式,就是关键域。

在每个线程都执行同一段代码,在这段代码的上下加锁,一次只能进入一个线程处理


一个不太雅观的说法是:

CriticalSection(临界区) 类似于只有一个蹲位的公共厕所, 只能一个个地进;

Mutex(互斥) 对象类似于接力赛中的接力棒, 某一时刻只能一个人持有, 谁拿着谁跑.


每一个子线程都要执行同样的函数,在这个函数中的公共资源的要放入临界区内


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值