任务要求:
生产者—消费者之间设置一个具有n个缓存区的缓冲池,生产者进程将他所生产的产品放入一个缓冲;消费者进程可以从一个缓冲区中取走产品去消费。老板不允许消费者进程到一个空缓冲去取产品。老板不允许生产者进程向一个已装满产品且尚未取走的缓冲区投放产品。
使用多线程实现生产者和消费者问题模型,使用锁和信号量控制线程之间的同步。
为了完成本关任务,你需要掌握:1.多线程相关的系统调用,2.使用锁控制进程互斥,3.使用信号量控制进程同步
此时确实也就确实是在要求我们要掌握这方面的知识而不能再一知半解下去了emmm…
掰扯掰扯之前学的点点东西:
pthread_create
创建进程的函数
pthread_join
线程等待
偷来的原话:pthread_create
调用成功以后,新线程和老线程谁先执行,谁后执行用户是不知道的,这一块取决与操作系统对线程的调度,如果我们需要等待指定线程结束,需要使用pthread_join
函数
结合上次的:
*tidp
是pthread_t
类型,也就是指向线程标识符的指针
这里: pthread_t th //th是要等待结束的线程的标识
也没什么错,是线程的标识
void *thread_return //指针thread_return指向的位置存放的是终止线程的返回状态。
也就可以pthread_join(th,&thread_return);
在主线程中初始化锁为解锁状态
pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL);
访问对象时的加锁操作与解锁操作
加锁 pthread_mutex_lock(&mutex)
释放锁 pthread_mutex_unlock(&mutex)
从其他地方查的解释:互斥锁用于上锁,条件变量用于等待。
还是不太清楚。
先引入头文件 #include
初始化信号量: int sem_init(sem_t \*sem, int pshared, unsigned int value);
成功返回0,失败返回-1
参数
sem:指向信号量结构的一个指针
pshared: 不是0的时候,该信号量在进程间共享,否则只能为当前进程的所有线程们共享
value:信号量的初始值
信号量减1操作,当sem=0的时候该函数会堵塞 int sem_wait(sem_t *sem);
成功返回0,失败返回-1
参数
sem:指向信号量的一个指针
信号量加1操作 int sem_post(sem_t *sem);
参数与返回同上
销毁信号量 int sem_destroy(sem_t *sem);
参数与返回同上
不过不得不说还是没怎么学到太多干货啊emmm…
void *Consumer()
{
int nex=0;
for(int i=0;i<10;i++)
{
int time = rand()%10+1;
pthread_mutex_lock(&mutex);
nex = nex + 1;
buffer[in] = nex;
printf("Consume one message:%d\n", nex);
fflush(stdout);//printf后请一定调用这句刷新输出缓存
in = (in + 1) % SIZE;
pthread_mutex_unlock(&mutex); //互斥锁解锁
sem_post(&full);
}
}
顺便看看它的主函数:
int main()
{
sem_init(&empty, 0, 10); //信号量初始化(最多容纳10条消息,容纳了10条生产者将不会生产消息)
sem_init(&full, 0, 0);
pthread_mutex_init(&mutex, NULL); //互斥锁初始化
pthread_t producid;
pthread_t consumid;
pthread_create(&producid, NULL, Producer, NULL); //创建生产者线程
pthread_create(&consumid, NULL, Consumer, NULL); //创建消费者线程
pthread_join(producid, NULL);
pthread_join(consumid, NULL);
sem_destroy(&empty); //信号量的销毁
sem_destroy(&full);
pthread_mutex_destroy(&mutex); //互斥锁的销毁
return 0;
}
任务描述:
桌上有个能盛的下五个水果的空盘子。爸爸不停的向盘中放苹果或桔子,儿子不停的从盘中取出桔子享用,女儿不停的从盘中取出苹果享用。规定三人不能同时从盘中取放水果。试用信号量实现爸爸、儿子和女儿这三个进程之间的同步
这个有点凶,里面有个wait()函数
去偷了波,函数功能:父进程一旦调用了wait就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。
wait()函数相关说明链接
void *Son()
{
while(1)
{
int time = rand() % 10 + 1;
sem_wait(&orange);
pthread_mutex_lock(&mutex);
printf("儿子取了一个桔子\n") ;
fflush(stdout);
pthread_mutex_unlock(&mutex); //互斥锁解锁
sem_post(&empty);
}
}
来个主函数:
int main()
{
sem_init(&empty, 0, 5); //信号量初始化
sem_init(&orange, 0, 0);
sem_init(&apple, 0, 0);
pthread_mutex_init(&mutex, NULL); //互斥锁初始化
pthread_t dadid;
pthread_t daughterid;
pthread_t sonid;
pthread_create(&dadid, NULL, Dad, NULL); //创建爸爸线程
pthread_create(&daughterid, NULL, Daughter, NULL); //创建女儿线程
pthread_create(&sonid, NULL, Son, NULL); //创建儿子线程
pthread_join(daughterid, NULL);
pthread_join(sonid, NULL);
sem_destroy(&empty); //信号量的销毁
sem_destroy(&apple);
sem_destroy(&orange);
pthread_mutex_destroy(&mutex); //互斥锁的销毁
return 0;
}