利用生产者消费者模型实现大文件的拷贝

代码如下,一般10个生产者10个消费者拷贝1个g的文件大概在6s左右,速度还是不错的。

  1 #include <semaphore.h>
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #include <fcntl.h>
  5 #include <pthread.h>
  6 #include <sys/stat.h>
  7 #include <unistd.h>
  8 #include <time.h>
  9
 10 #define NBUFF 10
 11 #define MAXTHREAD 1000
 12 int nitems, nproducers, nconsumers;
 13 int fin;
 14 int fout;
 15
 16 struct{
 17     struct{
 18         char data[BUFSIZ];
 19         ssize_t n ;
 20     }buff[NBUFF];//多个缓冲区
 21     int nput;
 22     int nget;
 23     sem_t mutex, nempty, nstored;
 24 } shared;
 25
 26
 27 void * produce(void *), *consume(void *);
 28
 29 int
 30 main(int argc, char ** argv)
 31 {
 32     time_t startTime, endTime;
 33     int i, prodcount[MAXTHREAD], conscount[MAXTHREAD];
 34     pthread_t tid_produce[MAXTHREAD], tid_consume[MAXTHREAD];
 35     if(argc != 5){
 36         perror("Invalid argument!\n");
 37         exit(0);
 38     }
 39     nproducers = atoi(argv[1]);
 40     nconsumers = atoi(argv[2]);
 41
 42
 43     fin = open(argv[3], O_RDONLY);
 44     fout = open(argv[4], O_CREAT | O_RDWR | O_TRUNC);
 45
 46     sem_init(&shared.mutex, 0, 1);
 47     sem_init(&shared.nempty, 0, NBUFF);
 48     sem_init(&shared.nstored, 0, 0);
 49
 50     //shared.nget = 0;
 51     //shared.nput = 0;
 52
 53     pthread_setconcurrency(nproducers + nconsumers);
 54
 55     time(&startTime);
 56     for(i = 0; i < nproducers; ++i){
 57         prodcount[i] = 0;
 58         pthread_create(&tid_produce[i], NULL, produce, &prodcount[i]);
 59     }
 60
 61     for(i = 0; i < nconsumers; ++i){
 62         conscount[i] = 0;
 63         pthread_create(&tid_consume[i], NULL, consume, &conscount[i]);
 64     }
 65
 66     for(i = 0; i < nproducers; i++){
 67         pthread_join(tid_produce[i], NULL);
 68         printf("producer count[%d] = %d\n", i, prodcount[i]);
 69     }
 70
 71     for(i = 0; i < nconsumers; i++){
 72         pthread_join(tid_consume[i], NULL);
 73         printf("consumer connt[%d] = %d\n", i, conscount[i]);
 74     }
 75     close(fin);
 76     close(fout);
 77
 78     time(&endTime);
 79     printf("The total time cost is : %.3f seconds\n", difftime(endTime, startTime));
 80
 81     sem_destroy(&shared.mutex);
 82     sem_destroy(&shared.nempty);
 83     sem_destroy(&shared.nstored);
 84     exit(0);
 85 }
 86
 87 void * produce(void * arg)
 88 {
 89     for(;;){
 90         sem_wait(&shared.nempty);
 91         sem_wait(&shared.mutex);
 92
 93         shared.buff[shared.nput%NBUFF].n =
 94                 read(fin, shared.buff[shared.nput%NBUFF].data, BUFSIZ);
 95         if(shared.buff[shared.nput%NBUFF].n == 0){
 96             printf("asdasd\n");
 97             sem_post(&shared.nstored);
 98             sem_post(&shared.nempty);
 99             sem_post(&shared.mutex);
100             return NULL;
101         }
102         shared.nput++;
103
104         sem_post(&shared.mutex);
105         sem_post(&shared.nstored);
106         ++*((int*)arg);
107     }
108 }
109
110 void * consume(void * arg)
111 {
112     for(;;){
113         sem_wait(&shared.nstored);
114         sem_wait(&shared.mutex);
115
116         if(shared.buff[shared.nget%NBUFF].n == 0){
117             sem_post(&shared.nstored);
118             sem_post(&shared.mutex);
119             return (NULL);
120         }
121         write(fout, shared.buff[shared.nget%NBUFF].data, shared.buff[shared.nget%NBUFF].n);
122         if(!(shared.nget%10000))
123             printf("Process is going on, please wait...\n");
124         shared.buff[shared.nget%NBUFF].n = 0;
125         shared.nget++;
126         sem_post(&shared.mutex);
127         sem_post(&shared.nempty);
128         ++*((int*)arg);
129     }
130 }
时间: 2024-10-24 14:49:26

利用生产者消费者模型实现大文件的拷贝的相关文章

Java多线程15:Queue、BlockingQueue以及利用BlockingQueue实现生产者/消费者模型

Queue是什么 队列,是一种数据结构.除了优先级队列和LIFO队列外,队列都是以FIFO(先进先出)的方式对各个元素进行排序的.无论使用哪种排序方式,队列的头都是调用remove()或poll()移除元素的.在FIFO队列中,所有新元素都插入队列的末尾. Queue中的方法 Queue中的方法不难理解,6个,每2对是一个也就是总共3对.看一下JDK API就知道了: 注意一点就好,Queue通常不允许插入Null,尽管某些实现(比如LinkedList)是允许的,但是也不建议. Blockin

利用生产者消费者模型和MQ模型写一个自己的日志系统-并发设计里一定会用到的手段

一:前言 写这个程序主要是用来理解生产者消费者模型,以及通过这个Demo来理解Redis的单线程取原子任务是怎么实现的和巩固一下并发相关的知识:这个虽然是个Demo,但是只要稍加改下Appender部分也是可以用于项目中的,假设项目里确实不需要log4j/logback之类的日志组件的时候: 二:实现方式 1.利用LinkedList作为MQ(还可以用jdk自带的LinkedBlockingQueue,不过这个Demo主要是为了更好的理解原理因此写的比较底层): 2.利用一个Daemon线程作为

4.利用python生成器实现简单的“生产者消费者”模型

假如说,没有生成器这种对象,那么如何实现这种简单的"生产者消费者"模型呢? import time def producer(): pro_list = [] for i in range(10000): print "包子%s制作ing" %(i) time.sleep(0.5) pro_list.append("包子%s" %i) return pro_list def consumer(pro_list): for index,stuffe

13 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件  queue队列 生产者消费者模型 Queue队列 开发一个线程池

本节内容 操作系统发展史介绍 进程.与线程区别 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者消费者模型 Queue队列 开发一个线程池 进程 语法 进程间通讯 进程池 操作系统发展史 手工操作(无操作系统) 1946年第一台计算机诞生--20世纪50年代中期,还未出现操作系统,计算机工作采用手工操作方式. 手工操作程序员将对应于程序和数据的已穿孔的纸带(或卡片)装入输入机,然后启动输入机把

生产者消费者模型实现多线程异步交互

[Python之旅]第六篇(五):生产者消费者模型实现多线程异步交互 消息队列 生产者消费者模型 多线程异步交互 摘要:  虽然标题是"生产者消费者模型实现多线程异步交互",但这里要说的应该还包括Python的消息队列,因为这里多线程异步交互是通过Python的消息队列来实现的,因此主要内容如下: 1 2 3 4 1.生产者消费者模型:厨师做包子与顾客吃包子 2.Python的消息队列 3.利用... 虽然标题是"生产者消费者模型实现多线程异步交互",但这里要说的应

进击的Python【第九章】:paramiko模块、线程与进程、各种线程锁、queue队列、生产者消费者模型

一.paramiko模块 他是什么东西? paramiko模块是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接. 先来个实例: 1 import paramiko 2 # 创建SSH对象 3 ssh = paramiko.SSHClient() 4 5 # 允许连接不在know_hosts文件中的主机 6 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 7 # 连接服务器 8 ss

35 守护进程 互斥锁 IPC 共享内存 的方式 生产者消费者模型

守护进程 进程:一个正在运行的程序. 主进程创建守护进程: 1.守护进程会在主进程代码执行结束后就终止, 2.守护进程内无法再开启子进程,否则抛出异常. 注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即终止. 例子:from multiprocessing import Processimport time def task(): print('老了....') time.sleep(2) print('睡了一会..') if __name__ == '__main__': prin

队列、生产者消费者模型

目录 队列.生产者消费者模型.初识线程 一.用进程锁来优化抢票小程序 1.1 进程锁 1.2 优化抢票小程序 二.队列 2.1 队列的介绍 2.2 创建队列的类 2.3 使用队列的案例 三.生产者消费者模型 3.1 用队列Queue实现生产者消费者模型 3.2 用队列JoinableQueue实现生产者消费者模型 队列.生产者消费者模型.初识线程 一.用进程锁来优化抢票小程序 1.1 进程锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端是没有问题的.而共享带来

python2.0_s12_day9之day8遗留知识(queue队列&amp;生产者消费者模型)

4.线程 1.语法 2.join 3.线程锁之Lock\Rlock\信号量 4.将线程变为守护进程 5.Event事件 * 6.queue队列 * 7.生产者消费者模型 4.6 queue队列 queue非常有用,当信息必须安全的在多个线程之间进行数据交换的时候就应该想到queue 所以,queue它能保证数据被安全的在多个线程之间进行交换,那他就是天生的线程安全. queue有那么几种: class queue.Queue(maxsize=0) # 先入先出 class queue.LifoQ