`
envy2002
  • 浏览: 153056 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

linux c 多线程 生产者--消费者

阅读更多

linux 线程同步机制和java的是极其类似的。如果不太明白java多线程编程,可以参考我原先写的java多线程编程。下面我们将展现linux下如何实现生产者和消费者模型。

 

直接上代码吧:

 #ifndef _LIST_H_

#define _LIST_H_
#include <string.h>
#include <stdio.h>

struct List
{
	char buffer[10];
	char * cursor;
	char * begin;
	char * end;
	
};
// you must add struct, otherwise it will prompt "expected ‘)’ before ‘*’ token"
void init(struct List * p_list);
int get_buffer_length (struct List * p_list);
void put_into_buffer(struct List* p_list,char *pc_char);
char get_from_buffer(struct List* p_list);


#endif

 这个头文件主要实现了一个数据结构,List,先进先出。

 

#include "list.h"

void init(struct List * p_list){
	
	memset(p_list->buffer,'\0',10);
	p_list->cursor=(p_list->buffer)+10;
	p_list->begin=p_list->buffer;
	p_list->end=(p_list->buffer)+10;
	
	
}
int get_buffer_length(struct List * p_list){
	
	return p_list->end-p_list->cursor;
}

void put_into_buffer(struct List * p_list,char * pc_char){
	printf("put ........  %c\n",*pc_char);
	if(p_list->cursor<=p_list->begin||p_list->cursor>p_list->end)
		printf(" put error");
	//put the char into cursor's former place
	(p_list->cursor)--;
	memset(p_list->cursor,(int)(*pc_char),1);
	
	
	
}

char get_from_buffer(struct List * p_list){
	if(p_list->cursor<p_list->begin||p_list->cursor>p_list->end)
		printf(" get error");
	//put the char into cursor's former place
	char result=*(p_list->cursor);
	(p_list->cursor)++;
	printf("get ......... %c\n",result);
	return result;
}

 List的具体实现。

 

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

pthread_cond_t has_product = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

//define the Producer thread
void * produce(void * arg)
{
	//arg is a char * pointer
	struct List * p_list=(struct List *)arg;
	//if buffer length =10,than wait,because buffer is full,
	
	while(1)
	{
		pthread_mutex_lock(&lock);  //正确位置,
		printf("111111\n");
		if(get_buffer_length(p_list)==10)
		{
			printf("22222222\n");
			int num1=pthread_cond_wait(&has_product, &lock);
			printf("33333333\n");
			printf(" num11111 %d\n",num1);
				
		}
		//buffer'length !=10,not full, we can put char into buffer.
		printf("444444\n");
		//pthread_mutex_lock(&lock); //错误位置
		printf("555555\n");
		char zifu=(char)(1+(int)(128.0*rand()/(RAND_MAX+1.0)));
		put_into_buffer(p_list,&zifu);
		//after put, if the length>0,we can notify the wait thread,means that you can get char now
		if(get_buffer_length(p_list)==1)
		{
			pthread_cond_signal(&has_product);	
			printf("66666\n");
		}
		printf("777777777777\n");
		int num3=pthread_mutex_unlock(&lock);
		printf("unlocknumber  1111111111111 is %d\n",num3);
		printf("888888888888\n");
		sleep(1);
	    printf("99999999\n");
   }
	
}

//define the second thread
void * comsume(void * arg)
{	
	//arg is a char * pointer
	struct List * p_list=(struct List *)arg;
	while(1)
	{
		//if buffer length =10,than wait,because buffer is full,
		pthread_mutex_lock(&lock);  //正确位置,
		printf("aaaaaaaaaa\n");
		if(get_buffer_length(p_list)==0)
		{
			printf("bbbbbbbbbbbbbb\n");
			int num2=pthread_cond_wait(&has_product, &lock);
			printf("cccccccccccc\n");				
			printf(" num2222 %d\n",num2);
				
		}
		//buffer'length !=0,not full, we can get char into buffer.
		printf("dddddddddddddddd\n");
		//int num4=pthread_mutex_lock(&lock); //错误位置
		//printf("unlocknumber 222222222 is %d\n",num4);
		printf("eeeeeeeeeeeeee\n");
		char zifu=get_from_buffer(p_list);
		//after get, if the length<10,we can notify the put thread,means that you can put now!
		if(get_buffer_length(p_list)<10)
		{
			pthread_cond_signal(&has_product);	
		}
		printf("ffffffffffff\n");
		pthread_mutex_unlock(&lock);
		printf("gggggggggggg\n");
	    sleep(2);
	    printf("hhhhhhhhhhhhhh\n");
   }
	
}

int main (int argc, char ** argv)
{
	pthread_t tidA, tidB;
    struct List common;
    init(&common);
	
	pthread_create(&tidB, NULL, &comsume, &common);
	
	sleep(3);
	
	pthread_create(&tidA, NULL, &produce, &common);
	sleep(120);
	
	
	return 0;
}

 这个是具体的模型实现,特别注意的是produce和consume方法里面,我注释了,加锁的正确位置和错误位置。如果加锁的位置在错误位置会引起死锁,具体方法,还是用“颜色”分析方法。

首先cosumer进行wait,使其在mutex上进入等待队列,线程切换到produce线程上面执行,然后produce释放锁,consumer居然又要lock mutex,所以互斥,consumer线程就死了,然后produce循环过来,也要lock mutex,所以produce线程也死了。就这样,正确lock mutex位置在文中进行了标注。

分享到:
评论

相关推荐

    Linux c语言多线程实现生产者/消费者问题

    以生产者/消费者问题为例来阐述Linux线程的控制和通信。一组生产者线程与一组消费者线程通过缓冲区发生联系。生产者线程将生产的产品送入缓冲区,消费者线程则从中取出产品。缓冲区有N 个,是一个环形的缓冲池。 ...

    多线程同步方法解决生产者-消费者问题(linux线程实现)

    设计要求:(1)每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容,当前指针位置和生产者/消费者线程的标识符.(2)生产者和消费者各有两个以上.(3)多个生产者或多个消费者之间须有共享对缓冲区...

    使用多线程程序模拟实现单生产者/多消费者问题(Linux下C语言)。

    使用多线程程序模拟实现单生产者/多消费者问题。 要求“生产者”随机产生一个整数,“消费者 1”将这个整数加 1 后输出,“消 费者 2”将这个整数加 2 后输出,“消费者 3”将这个整数加 3 后输出,“消 费者 4”将...

    linux进程链、进程扇和信号量实现生产者--消费者模型实验报告

    通过对生产者-消费者模型的实现,学生将学习如何在Linux环境下运用无名信号量来保护临界资源,同时提升对文件I/O操作的掌握。 二、实验内容 实验分为三个部分: 1. 使用链式结构创建10个子进程,形成进程链。 2. ...

    linux下多线程模拟实验

    在这个"Linux下多线程模拟实验"中,我们将深入探讨如何使用C语言在Linux环境下实现生产者-消费者问题,这是一个经典的线程同步问题。 生产者-消费者问题是多线程编程中的一个经典案例,主要用于演示如何通过共享...

    用多线程同步方法解决生产者-消费者问题(操作系统课设)

    针对生产者-消费者问题,多线程同步方法提供了一种有效且可靠的解决方案。在本课程设计中,采用的是Linux环境下的C语言编程,利用了信号量(Semaphore)和互斥锁(Mutex)来实现线程间的同步和互斥访问。 - **信号...

    (Linux C)利用多进程或多线程模拟实现生产者/消费者问题

    以下是对"Linux C"环境下,利用多进程或多线程实现生产者/消费者问题的详细解释: 首先,我们需要了解基础概念: 1. **多进程**:在Linux系统中,每个进程都有自己的独立内存空间,它们之间的通信通常通过文件、...

    操纵系统课程设计生产者-消费者

    - GCC编译器是Linux下的标准C编译器,能支持C语言和C++,可以用来编译和链接生产者-消费者模型的代码。 - VI编辑器是Linux下的文本编辑器,用于编写源代码。 3. **C语言实现**: - C语言是底层编程的语言,适合...

    生产者消费者程序-Linux

    生产者消费者模型是一种经典的多线程同步问题,广泛应用于计算机科学和操作系统...以上是对"生产者消费者程序-Linux"的详细解析,通过理解并实践这个模型,你可以更好地掌握多线程同步、资源管理和并发编程的核心概念。

    (Linux C)利用多进程或多线程模拟实现生产者/消费者问题。

    (Linux C)利用多进程或多线程模拟实现生产者/消费者问题。

    Linux环境下C语言实现生产者消费者问题的代码

    在Linux下完整C语言实现生产者消费者问题的代码。其中涉及信号量、多线程、GCC编译、PV操作等基础知识。Linux下通过gcc - o yy xxx.c -pthread,再通过./yy即可运行。

    生产者消费者 Linux代码

    5. **多线程**:为了模拟生产者和消费者的行为,代码可能创建了两个或多个线程,一个代表生产者,一个代表消费者。每个线程都有自己的逻辑,按照预定的规则与缓冲区交互。 运行说明.txt文件可能包含了如何编译和...

    生产者与消费者多线程编程(图书馆案例)(加锁)

    此实例在windows 10系统上可以成功运行,可以修改一下,在linux上也可以运行,思路都是一样的。 说明:这个是个图书馆案例,默认100个座位,生产者与消费者各2个线程 (修改:加锁)

    linux课程设计 消费者生产者问题

    Linux课程设计中的“消费者-生产者问题”是一个经典的多线程同步问题,源自计算机科学的并发控制领域。这个问题由Edsger Dijkstra在1965年提出,它模拟了一个系统,其中生产者生成资源而消费者消耗这些资源,两者都...

    Linux 多线程实现生产者消费者模式.zip

    本文将深入探讨如何在Linux上使用C语言或C++实现多线程的生产者消费者模式。 首先,我们需要理解生产者消费者模型的基本概念。生产者是产生数据的一方,而消费者则是消耗这些数据的一方。在这个模型中,通常有一个...

    linux c实现生产者 消费者程序

    在Linux环境下,使用C语言实现这样的程序通常涉及到多线程、同步原语和共享内存等概念。本文将详细讲解如何利用C语言在Linux下构建一个简单的生产者-消费者模型。 首先,我们需要理解基本的结构。生产者-消费者模型...

    操作系统生产者——消费者模拟程序

    操作系统中的生产者-消费者问题是一个经典的多线程同步问题,源于1965年由Edsger Dijkstra提出的银行家算法。这个问题的设定是有一个共享资源(例如一个缓冲区),生产者线程负责生成数据并放入缓冲区,而消费者线程...

    C语言实现生产者消费者问题

    C语言实现生产者消费者问题,分配具有n个缓冲区的缓冲池,作为共享资源。 定义两个资源型信号量empty 和full,empty信号量表示当前空的缓冲区数量,full表示当前满的缓冲区数量。 定义互斥信号量mutex,当某个进程...

    linux下进程通信 和 生产者消费者c程序代码

    生产者-消费者问题是多线程和进程同步的经典案例。在这个问题中,生产者进程负责生成产品并放入一个有限大小的缓冲区,而消费者进程则负责从缓冲区取出并消费产品。问题的核心是如何保证缓冲区不被填满(防止生产过...

    大工20年《操作系统》答案进程同步与互斥生产者-消费者问题.pdf

    例如,可以使用Pthreads库在Linux环境下编写多线程程序,实现生产者和消费者线程,并使用互斥锁和条件变量来同步它们的行为。 最后,值得注意的是,在编写涉及多进程或线程的程序时,代码必须仔细设计以确保线程...

Global site tag (gtag.js) - Google Analytics