linux进程 生产者消费者

Posted 子都

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
",lock.l_pid);
		}
		else if(lock.l_type == F_WRLCK)
		{
			printf("Write lock alread set by %d
",lock.l_pid);
		}
	}
	lock.l_type = type;
	if((fcntl(fd,F_SETLKW,&lock)) < 0)
	{
		printf("Lock failed:type = %d
",lock.l_type);
		return -1;
	}
	switch(lock.l_type)
	{
		case F_RDLCK:
			{
				printf("Read lock set by %d
",getpid());
			}
			break;
		case F_WRLCK:
			{
				printf("Write lock set by %d
",getpid());
			}
			break;
		case F_UNLCK:
			{
				printf("Release lock by %d
",getpid());
			}
			break;
	}
	return 0;
}
int custum()
{
	int fs,fd;
	int count;
	char c;
	if((fs = open("produce.txt",O_RDWR)) < 0)
	{
		printf("open error
");
		return -1;
	}
//	if((fd = open("temp.txt",O_RDWR)) < 0)
//	{
//		printf("open error2
");
//		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!
");
			lock_set(fs,F_UNLCK);
			sleep(1);
			continue;
		}
		printf("get a character: %c 
",c);
	//	lseek(fs,0,SEEK_CUR);
	//	lseek(fd,0,SEEK_SET);
	//	count = 0;
		while(((count = read(fs,&c,1)) == 1) /*&& c!= ‘
‘*/)
		{
			printf("read fs: %c
", 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!=‘
‘*/)
		{
		//	printf("read fd: %c
", 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函数读到最后貌似自动会读一个‘ ‘。不加语句c!=‘ ‘的话,会将 一直复制下去。

生产者函数如下:

#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
",lock.l_pid);
		}
		else if(lock.l_type == F_WRLCK)
		{
			printf("Write lock alread set by %d
",lock.l_pid);
		}
	}
	lock.l_type = type;
	if((fcntl(fd,F_SETLKW,&lock)) < 0)
	{
		printf("Lock failed:type = %d
",lock.l_type);
		return -1;
	}
	switch(lock.l_type)
	{
		case F_RDLCK:
			{
				printf("Read lock set by %d
",getpid());
			}
			break;
		case F_WRLCK:
			{
				printf("Write lock set by %d
",getpid());
			}
			break;
		case F_UNLCK:
			{
				printf("Release lock by %d
",getpid());
			}
			break;
	}
	return 0;
}
int produce()
{
	int fd;
	char a=‘A‘;
	if((fd = open("produce.txt",O_WRONLY|O_APPEND)) < 0)
	{
		printf("open failed
");
		return -1;
	}
	while(1)
	{
		lock_set(fd,F_WRLCK);
		write(fd,&a,1);
		printf("hava produce one character %c 
",a);
		a++;
		lock_set(fd,F_UNLCK);
		sleep(3);
	}
	close(fd);
}
int main(int argc, const char *argv[])
{
	
	produce();
	return 0;
}

  

以上是关于linux进程 生产者消费者的主要内容,如果未能解决你的问题,请参考以下文章

(王道408考研操作系统)第二章进程管理-第三节6:经典同步问题之生产者与消费者问题

linux进程 生产者消费者

Linux多进程通信多生产者一消费者

linux:线程&&多线程 初见

Linux进程内消息总线设计

SpringCloud系列十一:SpringCloudStream(SpringCloudStream 简介创建消息生产者创建消息消费者自定义消息通道分组与持久化设置 RoutingKey)(代码片段