国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Linux 基本語(yǔ)句_9_C語(yǔ)言_生產(chǎn)者&消費(fèi)者

這篇具有很好參考價(jià)值的文章主要介紹了Linux 基本語(yǔ)句_9_C語(yǔ)言_生產(chǎn)者&消費(fèi)者。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

完整版生產(chǎn)者代碼:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/file.h> 
#include <string.h>

#define MAXLEN 10
#define ALPHABET 1
#define ALPHABET_START 'a'
#define COUNT_OF_ALPHABET 26
#define DIGIT 2
#define DIGIT_START '0'
#define COUNT_OF_DIGIT 10
#define SIGN_TYPE ALPHABET

const char * fifo_file = "./FIFO.txt";

char buf[MAXLEN];

int lock_set(int fd, int type){
	struct flock old_lock, lock;
	lock.l_whence = SEEK_SET; //加鎖區(qū)域?yàn)槲募_始處 
	lock.l_start = 0;//加鎖區(qū)域在文件位置的相對(duì)偏移量 
	lock.l_len = 0;//加鎖區(qū)域長(zhǎng)度 
	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 already set by %d\n", lock.l_pid);
	   }
	   else if(lock.l_type == F_WRLCK){
	   	printf("Write lock already set by %d\n", lock.l_pid);
	   } 
	} 
	
	/*上述可能由于不是解鎖狀態(tài)l_type被設(shè)置成了相應(yīng)的鎖值下方進(jìn)行上鎖操作時(shí)要再次調(diào)用type*/ 
	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());//獲取當(dāng)前進(jìn)程的ID
			break;
		case F_WRLCK:
		    printf("Write lock set by %d\n", getpid());
	        break;
		case F_UNLCK:
		    printf("Release lock by %d\n", getpid());//解鎖返回1 
			return 1;
			break; 
	}
	
	return 0;//上鎖返回0 
}

int product(void){
	int fd;
	unsigned int sign_type, sign_start, sign_count, size;
	static unsigned int counter = 0;//只會(huì)執(zhí)行一次 
	if((fd = open(fifo_file, O_WRONLY|O_APPEND)) < 0){//只寫方式打開 ,追加模式 
	   perror("open error");
	   return -1;
    }
    sign_type = SIGN_TYPE;//英文字符集合 
    
    switch(sign_type){
    	case ALPHABET:
		     sign_start = ALPHABEF_START;
			 sign_count = COUNT_OF_ALPHABET;//26
			 break;
		case DIGIT:
		    sign_start = DIGIT_START;
			sign_count = COUNT_OF_DIGIT;
			break;
		default:
		    return -1; 
	}
	
	sprintf(buf, "%c", (sign_start + counter));//將字符寫入buf緩沖區(qū)
	counter = (counter + 1) % sign_count;
	
	lock_set(fd, F_WRLCK);//寫鎖
	
	if((size = write(fd, buf, strlen(buf))) < 0){//打開失敗,否者寫入 
		perror("producer:write error");
		return -1; 
	}
	lock_set(fd, F_UNLCK);//解鎖
	
	close(fd);
	return 0; 
}

int main(int argc, const char * argv[]){
	int time_step = 1;//周期 
	int time_life = 10;//生產(chǎn)數(shù)量
	
	close(open(fifo_file, O_REONLY|O_CREAT|O_TRUNC, 0664));//創(chuàng)建文件 
	
	if(argc > 1){
		sscanf(argv[1], "%d", &time_step);//將argv[1]轉(zhuǎn)成整數(shù)存入time_step中 
	}
	
	if(argc > 2){
		sscanf(argv[2], "%d", &time_life);
	} 
	
	while(time_life --){
		if(product() < 0){
			break;
		} 
		sleep(time_step);
	}
	return 0;
}

流程:
Linux 基本語(yǔ)句_9_C語(yǔ)言_生產(chǎn)者&消費(fèi)者,linux,c語(yǔ)言,算法

原版代碼有點(diǎn)缺失和問(wèn)題,添加的代碼如下:

原版代碼缺少創(chuàng)建文件函數(shù),以及沒(méi)有對(duì)文件清空的函數(shù)
每次啟動(dòng)一輪生產(chǎn),為了方便觀察將文件上次生產(chǎn)的內(nèi)容清空:

close(open(fifo_file, O_REONLY|O_CREAT|O_TRUNC, 0664));//創(chuàng)建文件&清空

文件打開模式必須是追加模式,否則生產(chǎn)的新數(shù)據(jù)會(huì)覆蓋原有數(shù)據(jù):

if((fd = open(fifo_file, O_WRONLY|O_APPEND)) < 0)

運(yùn)行效果:

FIFO.txt文件上次運(yùn)行時(shí)殘留有數(shù)據(jù)
Linux 基本語(yǔ)句_9_C語(yǔ)言_生產(chǎn)者&消費(fèi)者,linux,c語(yǔ)言,算法

生產(chǎn)五個(gè)數(shù)據(jù):
Linux 基本語(yǔ)句_9_C語(yǔ)言_生產(chǎn)者&消費(fèi)者,linux,c語(yǔ)言,算法
文件之前生產(chǎn)信息被清除,取而代之的是新數(shù)據(jù):

Linux 基本語(yǔ)句_9_C語(yǔ)言_生產(chǎn)者&消費(fèi)者,linux,c語(yǔ)言,算法

完整版消費(fèi)者代碼:

 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <sys/file.h> 
 #include <string.h>
 
 #define MAX_FILE_SIZE 100 * 1024 * 102
 
 
 const char *fifo_file  = "./FIFO.txt";
                                       
 const char *temp_file = "./temp";
 

int lock_set(int fd, int type){
        struct flock old_lock, lock;
        lock.l_whence = SEEK_SET; //加鎖區(qū)域?yàn)槲募_始處 
        lock.l_start = 0;//加鎖區(qū)域在文件位置的相對(duì)偏移量 
        lock.l_len = 0;//加鎖區(qū)域長(zhǎng)度 
        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 already set by %d\n", lock.l_pid);
              }
             else if(lock.l_type == F_WRLCK){
                 printf("Write lock already set by %d\n", lock.l_pid);
            }
      }                     
     /*上述可能由于不是解鎖狀態(tài)l_type被設(shè)置成了相應(yīng)的鎖值下方進(jìn)行上鎖操作時(shí)要再次調(diào)用type*/ 
    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());//獲取當(dāng)前進(jìn)程的ID
                    break;                                                                     
        case F_WRLCK:
                    printf("Write lock set by %d\n", getpid());
                    break;
        case F_UNLCK:
                    printf("Release lock by %d\n", getpid());//解鎖返回1 
                    return 1;
                    break;
    }
    return 0;//上鎖返回0 
}

int customing(const char * myfifo, int need){
        int fd;
        char buf;
        int counter = 0;
        if((fd = open(myfifo, O_RDONLY)) < 0){//只讀 
            perror("FunctI/On customing error");
            return -1;
        }
        printf("Enjoy:");
        lseek(fd, SEEK_SET, 0);
        while(counter < need){
           
           while((read(fd, &buf, 1) == 1) && (counter < need)){//read期望讀取的字符數(shù)與實(shí)際所讀一樣&&.... 
              fputc(buf, stdout);//打印到顯示屏 
              counter ++;
           }
           
        }
        fputs("\n", stdout);
         

        close(fd);
        return 0;
}                                                                                                         

int myfilecopy(const char * sour_file, const char * dest_file, int offset, int count, int copy_mode){
        int in_file, out_file;
        int counter = 0;
        char buff_unit;

        if((in_file = open(sour_file, O_RDONLY|O_NONBLOCK)) < 0){//非阻塞只讀 
            perror("FunctI/On my filecopy error int source file\n");
            return -1;
        }

        if((out_file = open(dest_file, O_RDWR|O_CREAT|O_TRUNC|O_NONBLOCK, 0664)) < 0){//非阻塞&打開或創(chuàng)建 
            perror("FUNCTI/O myfilecopy error in destinatI/on file");
            return -1;
        }
        lseek(in_file, offset, SEEK_SET);//設(shè)置指針到指定位置

        while((read(in_file, &buff_unit, 1) == 1) && (counter < count)){//讀取 
            write(out_file, &buff_unit, 1);//寫入 
            counter ++;
        }

        close(in_file);
        close(out_file);
        return 0;
}

 int custom(int need){
         int fd;
         customing(fifo_file, need);//取
 
         if((fd = open(fifo_file, O_RDWR)) < 0){//讀寫方式打開 
             perror("FunctI/On myfilecopy error in source_file");
             return  -1;
         }
 
         lock_set(fd, F_WRLCK);//上鎖,寫入鎖 
         myfilecopy(fifo_file, temp_file, need, MAX_FILE_SIZE, 0);//將第一個(gè)文件內(nèi)容復(fù)制到另一個(gè)文件,偏移>
         myfilecopy(temp_file, fifo_file, 0, MAX_FILE_SIZE, 0);
         lock_set(fd, F_UNLCK);//解鎖 
 
         unlink(temp_file);//刪除 
 
         close(fd);
         return 0;
 }

 int main(int argc, const char *argv[]){
         int customer_capacity = 0;
 
             if(argc > 1){
                sscanf(argv[1], "%d", &customer_capacity);//消費(fèi)數(shù)目寫入 
             }
 
             if(customer_capacity > 0){
               custom(customer_capacity);
             }
 
             return 0;
 }

流程:
Linux 基本語(yǔ)句_9_C語(yǔ)言_生產(chǎn)者&消費(fèi)者,linux,c語(yǔ)言,算法

這里對(duì)open函數(shù)進(jìn)行再次擴(kuò)充講解:

當(dāng)文件被一個(gè)進(jìn)程植入寫入鎖的時(shí)候,另一個(gè)進(jìn)程仍可以通過(guò)open函數(shù)獲取該文件的標(biāo)志位,但卻不能進(jìn)行read或write函數(shù)操作,因?yàn)闀?huì)受到寫入鎖的阻止

樸素的將寫入鎖是阻止其他進(jìn)程對(duì)文件的讀寫操作,而不是open操作

Linux 基本語(yǔ)句_9_C語(yǔ)言_生產(chǎn)者&消費(fèi)者,linux,c語(yǔ)言,算法
之前一直不理解為什么customing函數(shù)中下列語(yǔ)句不會(huì)報(bào)錯(cuò),通過(guò)用printf函數(shù)取點(diǎn)才發(fā)現(xiàn)問(wèn)題

if((fd = open(myfifo, O_RDONLY)) < 0){//只讀 
        perror("FunctI/On customing error");
        return -1;
}

看來(lái)看課本和懂課本是天差地別的

還有一點(diǎn)注意的是:

生產(chǎn)者代碼中的:

while(time_life --){
	if(product() < 0){
		break;
	} 
	sleep(time_step);
}

其中:

sleep(time_step);

這個(gè)延時(shí)語(yǔ)句作用巨大:

lock_set(fd, F_WRLCK);//上鎖,寫入鎖 
myfilecopy(fifo_file, temp_file, need, MAX_FILE_SIZE, 0);//將第一個(gè)文件內(nèi)容復(fù)制到另一個(gè)文件,偏移>
myfilecopy(temp_file, fifo_file, 0, MAX_FILE_SIZE, 0);
lock_set(fd, F_UNLCK);//解鎖

其作用是為了讓消費(fèi)者中這個(gè)文件挪動(dòng)語(yǔ)句能有時(shí)間完成
同時(shí)也用于讀取生產(chǎn)出來(lái)的字符:

while((read(in_file, &buff_unit, 1) == 1) && (counter < count)){//讀取 
        write(out_file, &buff_unit, 1);//寫入 
        counter ++;
    }

上述語(yǔ)句在字符未被生產(chǎn),或者文件被鎖住,會(huì)一直等待,直到解鎖或者有字符被生產(chǎn)

例如文件中生產(chǎn)abc,消費(fèi)a,所以挪位后為bc

效果:

已生產(chǎn)五個(gè)字符:
Linux 基本語(yǔ)句_9_C語(yǔ)言_生產(chǎn)者&消費(fèi)者,linux,c語(yǔ)言,算法

消費(fèi)四個(gè):
Linux 基本語(yǔ)句_9_C語(yǔ)言_生產(chǎn)者&消費(fèi)者,linux,c語(yǔ)言,算法

最后剩一個(gè):

Linux 基本語(yǔ)句_9_C語(yǔ)言_生產(chǎn)者&消費(fèi)者,linux,c語(yǔ)言,算法

同時(shí)進(jìn)行如下:

Linux 基本語(yǔ)句_9_C語(yǔ)言_生產(chǎn)者&消費(fèi)者,linux,c語(yǔ)言,算法
整個(gè)文件被鎖住,只出現(xiàn)在生產(chǎn)者將生產(chǎn)的字符寫入文件和文件挪動(dòng)這倆操作文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-725775.html

到了這里,關(guān)于Linux 基本語(yǔ)句_9_C語(yǔ)言_生產(chǎn)者&消費(fèi)者的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • go語(yǔ)言中實(shí)現(xiàn)生產(chǎn)者-消費(fèi)者模式有哪些方法呢

    本文將介紹在 Go 語(yǔ)言中實(shí)現(xiàn)生產(chǎn)者消費(fèi)者模式的多種方法,并重點(diǎn)探討了通道、條件變量的適用場(chǎng)景和優(yōu)缺點(diǎn)。我們將深入討論這些方法的特點(diǎn),以幫助開發(fā)者根據(jù)應(yīng)用程序需求選擇最適合的方式。通過(guò)靈活運(yùn)用 Go 語(yǔ)言提供的并發(fā)原語(yǔ),我們能夠?qū)崿F(xiàn)高效、可靠的生產(chǎn)者消

    2024年02月05日
    瀏覽(16)
  • Linux——生產(chǎn)者消費(fèi)者模型和信號(hào)量

    Linux——生產(chǎn)者消費(fèi)者模型和信號(hào)量

    目錄 ??????? 基于BlockingQueue的生產(chǎn)者消費(fèi)者模型 概念 條件變量的第二個(gè)參數(shù)的作用 ?鎖的作用 生產(chǎn)者消費(fèi)者模型的高效性 生產(chǎn)者而言,向blockqueue里面放置任務(wù) 消費(fèi)者而言,從blockqueue里面拿取任務(wù): 總結(jié) 完整代碼(不含存儲(chǔ)數(shù)據(jù)的線程) 完整代碼(含存儲(chǔ)線程)? 信

    2024年02月07日
    瀏覽(20)
  • Linux安裝Kafka,創(chuàng)建topic、生產(chǎn)者、消費(fèi)者

    Linux安裝Kafka,創(chuàng)建topic、生產(chǎn)者、消費(fèi)者

    1.創(chuàng)建安裝目錄/usr/local/kafka mkdir /usr/local/kafka 2.進(jìn)入安裝包目錄 cd?/usr/local/kafka? 3.下載安裝包 wget https://downloads.apache.org/kafka/3.3.1/kafka_2.12-3.3.1.tgz 4.解壓安裝包 tar -zxvf kafka_2.12-3.3.1.tgz 5.進(jìn)入cd kafka_2.12-3.3.1目錄 cd kafka_2.12-3.3.1/ 6.修改zookeeper配置 cat ./config/zookeeper.properties | grep

    2023年04月17日
    瀏覽(29)
  • Linux操作系統(tǒng)實(shí)驗(yàn):生產(chǎn)者和消費(fèi)者問(wèn)題

    Linux操作系統(tǒng)實(shí)驗(yàn):生產(chǎn)者和消費(fèi)者問(wèn)題

    “生產(chǎn)者消費(fèi)者”問(wèn)題是一個(gè)著名的同時(shí)性編程問(wèn)題的集合。通過(guò)編寫經(jīng)典的”生產(chǎn)者消費(fèi)者”問(wèn)題的實(shí)驗(yàn),讀者可以進(jìn)一步熟悉 Linux 中多線程編程,并且掌握用信號(hào)量處理線程間的同步互斥問(wèn)題。 VMware Workstation Pro “生產(chǎn)者消費(fèi)者”問(wèn)題描述如下。 有一個(gè)有限緩沖區(qū)和兩

    2024年02月06日
    瀏覽(37)
  • 【Linux】cp問(wèn)題,生產(chǎn)者消費(fèi)者問(wèn)題代碼實(shí)現(xiàn)

    【Linux】cp問(wèn)題,生產(chǎn)者消費(fèi)者問(wèn)題代碼實(shí)現(xiàn)

    生產(chǎn)者消費(fèi)者模式就是通過(guò)一個(gè)容器 來(lái)解決生產(chǎn)者和消費(fèi)者的強(qiáng)耦合問(wèn)題 。生產(chǎn)者和消費(fèi)者彼此之間不直接通訊,而通過(guò)阻塞隊(duì)列來(lái)進(jìn)行通訊,所以生產(chǎn)者生產(chǎn)完數(shù)據(jù)之后不用等待消費(fèi)者處理,直接扔給阻塞隊(duì)列,消費(fèi)者不找生產(chǎn)者要數(shù)據(jù),而是直接從阻塞隊(duì)列里取,阻塞

    2024年02月04日
    瀏覽(20)
  • 【Linux】基于環(huán)形隊(duì)列的生產(chǎn)者消費(fèi)者模型的實(shí)現(xiàn)

    【Linux】基于環(huán)形隊(duì)列的生產(chǎn)者消費(fèi)者模型的實(shí)現(xiàn)

    文章目錄 前言 一、基于環(huán)形隊(duì)列的生產(chǎn)者消費(fèi)者模型的實(shí)現(xiàn) 上一篇文章我們講了信號(hào)量的幾個(gè)接口和基于環(huán)形隊(duì)列的生產(chǎn)者消費(fèi)者模型,下面我們就快速來(lái)實(shí)現(xiàn)。 首先我們創(chuàng)建三個(gè)文件,分別是makefile,RingQueue.hpp,以及main.cc。我們先簡(jiǎn)單搭建一下環(huán)形隊(duì)列的框架: 首先我們

    2024年02月11日
    瀏覽(26)
  • 【Linux】生產(chǎn)者消費(fèi)者模型代碼實(shí)現(xiàn)和信號(hào)量

    【Linux】生產(chǎn)者消費(fèi)者模型代碼實(shí)現(xiàn)和信號(hào)量

    一定要先理解生產(chǎn)者消費(fèi)者模型的原理~ 文章目錄 一、生產(chǎn)者消費(fèi)者模型實(shí)現(xiàn)代碼 二、信號(hào)量 1.基于環(huán)形隊(duì)列的生產(chǎn)者消費(fèi)者模型 總結(jié) 下面我們實(shí)現(xiàn)基于阻塞隊(duì)列的生產(chǎn)消費(fèi)模型: 在多線程編程中阻塞隊(duì)列 (Blocking Queue) 是一種常用于實(shí)現(xiàn)生產(chǎn)者和消費(fèi)者模型的數(shù)據(jù)結(jié)構(gòu)。其

    2024年02月11日
    瀏覽(20)
  • 【linux】線程同步+基于BlockingQueue的生產(chǎn)者消費(fèi)者模型

    【linux】線程同步+基于BlockingQueue的生產(chǎn)者消費(fèi)者模型

    喜歡的點(diǎn)贊,收藏,關(guān)注一下把! 在線程互斥寫了一份搶票的代碼,我們發(fā)現(xiàn)雖然加鎖解決了搶到負(fù)數(shù)票的問(wèn)題,但是一直都是一個(gè)線程在搶票,它錯(cuò)了嗎,它沒(méi)錯(cuò)但是不合理。那我們應(yīng)該如何安全合理的搶票呢? 講個(gè)小故事。 假設(shè)學(xué)校有一個(gè)VIP學(xué)霸自習(xí)室,這個(gè)自習(xí)室有

    2024年02月03日
    瀏覽(24)
  • 『Linux』第九講:Linux多線程詳解(四)_ 生產(chǎn)者消費(fèi)者模型

    『Linux』第九講:Linux多線程詳解(四)_ 生產(chǎn)者消費(fèi)者模型

    「前言」文章是關(guān)于Linux多線程方面的知識(shí),上一篇是?Linux多線程詳解(三),今天這篇是 Linux多線程詳解(四),內(nèi)容大致是生產(chǎn)消費(fèi)者模型,講解下面開始! 「歸屬專欄」Linux系統(tǒng)編程 「主頁(yè)鏈接」個(gè)人主頁(yè) 「筆者」楓葉先生(fy) 「楓葉先生有點(diǎn)文青病」「每篇一句」

    2024年02月07日
    瀏覽(21)
  • Kafka 之生產(chǎn)者與消費(fèi)者基礎(chǔ)知識(shí):基本配置、攔截器、序列化、分區(qū)器

    Kafka 之生產(chǎn)者與消費(fèi)者基礎(chǔ)知識(shí):基本配置、攔截器、序列化、分區(qū)器

    kafaf集群地址列表:理論上寫一個(gè)節(jié)點(diǎn)地址,就相當(dāng)于綁定了整個(gè)kafka集群了,但是建議多寫幾個(gè),如果只寫一個(gè),萬(wàn)一宕機(jī)就麻煩了 kafka消息的key和value要指定序列化方法 kafka對(duì)應(yīng)的生產(chǎn)者id 使用java代碼表示則為以下代碼: ?可使用?retries 參數(shù) 進(jìn)行設(shè)置,同時(shí)要注意記住兩

    2024年02月05日
    瀏覽(30)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包