linux进程 生产者消费者

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>
int lock_set(int fd,int type)
{
	struct flock lock;
	lock.l_whence= SEEK_SET;
	lock.l_start = 0;
	lock.l_len = 0;
	lock.l_type = type;
	lock.l_pid = -1;
	fcntl(fd,F_GETLK,&lock);
	if(lock.l_type != F_UNLCK)
	{
		if(lock.l_type == F_RDLCK)
		{
			printf("Read lock alread set by %d\n",lock.l_pid);
		}
		else if(lock.l_type == F_WRLCK)
		{
			printf("Write lock alread set by %d\n",lock.l_pid);
		}
	}
	lock.l_type = type;
	if((fcntl(fd,F_SETLKW,&lock)) < 0)
	{
		printf("Lock failed:type = %d\n",lock.l_type);
		return -1;
	}
	switch(lock.l_type)
	{
		case F_RDLCK:
			{
				printf("Read lock set by %d\n",getpid());
			}
			break;
		case F_WRLCK:
			{
				printf("Write lock set by %d\n",getpid());
			}
			break;
		case F_UNLCK:
			{
				printf("Release lock by %d\n",getpid());
			}
			break;
	}
	return 0;
}
int custum()
{
	int fs,fd;
	int count;
	char c;
	if((fs = open("produce.txt",O_RDWR)) < 0)
	{
		printf("open error\n");
		return -1;
	}
//	if((fd = open("temp.txt",O_RDWR)) < 0)
//	{
//		printf("open error2\n");
//		return -1;
//	}
	while(1)
	{
		lock_set(fs,F_WRLCK);
		lseek(fs,0,SEEK_SET);
		fd=open("temp.txt",O_RDWR|O_CREAT|O_TRUNC,0777);
		count=read(fs,&c,1);
		if(count <= 0)
		{
			printf("no product!\n");
			lock_set(fs,F_UNLCK);
			sleep(1);
			continue;
		}
		printf("get a character: %c \n",c);
	//	lseek(fs,0,SEEK_CUR);
	//	lseek(fd,0,SEEK_SET);
	//	count = 0;
		while(((count = read(fs,&c,1)) == 1) /*&& c!= ‘\n‘*/)
		{
			printf("read fs: %c\n", c);
			write(fd,&c,count);
		}
		close(fs);
		fs = open("produce.txt",O_RDWR|O_TRUNC);
		//[email protected]
		lseek(fs,0,SEEK_SET);
		lseek(fd,0,SEEK_SET);
		while(((count = read(fd,&c,1)) == 1) /*&& c!=‘\n‘*/)
		{
		//	printf("read fd: %c\n", c);
			write(fs,&c,count);
		}
		unlink("temp.txt");
		close(fd);
		lock_set(fs,F_UNLCK);
		sleep(2);
	}
}

int main(int argc, const char *argv[])
{
	custum();

	return 0;
}

  运行程序时,生产文件里有ABC 3个产品,运行时发现最后一个C产品一直会重复取出,经检查发现:我将produce.txt中的剩余产品复制到temp.txt中,之后再复制回来,我只是将文件读写位置调到了起始,但是以读写方式打开文件produce.txt,其中的产品仍为ABC,将temp.txt中的BC复制回去时,只是覆盖AB为BC最后的C仍存在,所以会一直有C。解决这个问题是:关闭produce.txt的文件符,重新以读写,清除原文件内容的方式打开,就会成功。只是还有一个问题read函数读到最后貌似自动会读一个‘\n‘。不加语句c!=‘\n‘的话,会将\n一直复制下去。

生产者函数如下:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>
int lock_set(int fd,int type)
{
	struct flock lock;
	lock.l_whence = SEEK_SET;
	lock.l_start = 0;
	lock.l_len = 0;
	lock.l_type = type;
	lock.l_pid = -1;
	fcntl(fd,F_GETLK,&lock);
	if(lock.l_type != F_UNLCK)
	{
		if(lock.l_type == F_RDLCK)
		{
			printf("Read lock alread set by %d\n",lock.l_pid);
		}
		else if(lock.l_type == F_WRLCK)
		{
			printf("Write lock alread set by %d\n",lock.l_pid);
		}
	}
	lock.l_type = type;
	if((fcntl(fd,F_SETLKW,&lock)) < 0)
	{
		printf("Lock failed:type = %d\n",lock.l_type);
		return -1;
	}
	switch(lock.l_type)
	{
		case F_RDLCK:
			{
				printf("Read lock set by %d\n",getpid());
			}
			break;
		case F_WRLCK:
			{
				printf("Write lock set by %d\n",getpid());
			}
			break;
		case F_UNLCK:
			{
				printf("Release lock by %d\n",getpid());
			}
			break;
	}
	return 0;
}
int produce()
{
	int fd;
	char a=‘A‘;
	if((fd = open("produce.txt",O_WRONLY|O_APPEND)) < 0)
	{
		printf("open failed\n");
		return -1;
	}
	while(1)
	{
		lock_set(fd,F_WRLCK);
		write(fd,&a,1);
		printf("hava produce one character %c \n",a);
		a++;
		lock_set(fd,F_UNLCK);
		sleep(3);
	}
	close(fd);
}
int main(int argc, const char *argv[])
{

	produce();
	return 0;
}

  

原文地址:https://www.cnblogs.com/jiaan/p/9351202.html

时间: 2024-11-11 06:03:33

linux进程 生产者消费者的相关文章

Linux 信号量 生产者消费者小例题 (嘘,我是菜鸟~)

菜鸟偶遇信号量,擦出火花(只有不熟才会有火花).于是上网搜资料和看<Unix环境高级编程>实现了几个小例题,高手请勿喷!这几位写得非常好啊: 题目来源: http://www.it165.net/os/html/201312/7039.html 信号量及其用法:http://www.cnblogs.com/hjslovewcl/archive/2011/03/03/2314341.html Mutex与Semaphore区别著名的厕所理论:http://koti.mbnet.fi/niclas

LINUX学习:生产者&amp;消费者模型复习

回顾一下生产者消费者模型. #include <stdio.h> #include <stdlib.h> #include <string.h> #include <semaphore.h> #include <unistd.h> #include <sys/types.h> #include <pthread.h> #define ERR_EXIT(m) do { perror(m); exit(EXIT_FAILURE

linux ptheard 生产者消费者

1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pthread.h> 4  5 pthread_mutex_t mutex; 6 pthread_cond_t cond_full; 7 pthread_cond_t cond_empty; 8  9 int g_iBufSize = 0;10 11 void *thread_producer(void* arg)12 {13     while(true)14

Linux组件封装(五)一个生产者消费者问题示例

生产者消费者问题是计算机中一类重要的模型,主要描述的是:生产者往缓冲区中放入产品.消费者取走产品.生产者和消费者指的可以是线程也可以是进程. 生产者消费者问题的难点在于: 为了缓冲区数据的安全性,一次只允许一个线程进入缓冲区,它就是所谓的临界资源. 生产者往缓冲区放物品时,如果缓冲区已满,那么需要等待,一直到消费者取走产品为止. 消费者取走产品时,如果没有物品,需要等待,一直到有生产者放入为止. 第一个问题属于互斥问题,我们需要使用一把互斥锁,来实现对缓冲区的安全访问. 后两个属于同步问题,两类

Linux线程编程之生产者消费者问题

前言 本文基于顺序循环队列,给出Linux生产者/消费者问题的多线程示例,并讨论编程时需要注意的事项.文中涉及的代码运行环境如下: 本文假定读者已具备线程同步的基础知识. 一  顺序表循环队列 1.1 顺序循环队列定义 队列是一种运算受限的先进先出线性表,仅允许在队尾插入(入队),在队首删除(出队).新元素入队后成为新的队尾元素,元素出队后其后继元素就成为队首元素. 队列的顺序存储结构使用一个数组和两个整型变量实现,其结构如下: 1 struct Queue{ 2 ElemType elem[M

linux生产者消费者问题

(多进程+共享内存+信号量) 一.分析 生产者和消费者问题是多个相互合作的进程之间的一种抽象.生产者和消费者之间的关系: 1.  对缓冲区的访问是互斥的.由于两者都会修改缓冲区,因此,一方修改缓冲区时,另一方不能修改,这就是互斥. 2.  一方的行为影响另一方.缓冲区不空,才能消费,何时不空?生产了就不空:缓冲区满,就不能生产,何时不满?消费了就不满.这是同步关系. 为了描述这种关系,一方面,使用共享内存代表缓冲区:另一方面,使用 互斥信号量 控制对缓冲区的访问,使用同步信号量描述两者的依赖关系

Linux多线程实践(8) --Posix条件变量解决生产者消费者问题

Posix条件变量 int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr); int pthread_cond_destroy(pthread_cond_t *cond); int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); int pthread_cond_timedwait(pthread_cond_t *cond

Linux多线程实践(5) --Posix信号量与互斥量解决生产者消费者问题

Posix信号量 Posix 信号量 有名信号量 无名信号量 sem_open sem_init sem_close sem_destroy sem_unlink sem_wait sem_post 有名信号量 #include <fcntl.h> /* For O_* constants */ #include <sys/stat.h> /* For mode constants */ #include <semaphore.h> sem_t *sem_open(co

Python学习笔记——进阶篇【第九周】———线程、进程、协程篇(队列Queue和生产者消费者模型)

Python之路,进程.线程.协程篇 本节内容 进程.与线程区别 cpu运行原理 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者消费者模型 Queue队列 开发一个线程池 进程 语法 进程间通讯 进程池 参考链接http://www.cnblogs.com/alex3714/articles/5230609.html