Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何使用共享内存和信号量同步两个子fork进程?_C_Linux_Fork_Semaphore_Shared Memory - Fatal编程技术网

C 如何使用共享内存和信号量同步两个子fork进程?

C 如何使用共享内存和信号量同步两个子fork进程?,c,linux,fork,semaphore,shared-memory,C,Linux,Fork,Semaphore,Shared Memory,我不得不在linux上做一个关于同步和信号量的小项目,我遇到了一些麻烦。。。 问题是我想创建两个进程,子进程1(PP1)和子进程2(PP2),PP1按部分(16个字符)从文件中读取数据,并将它们保存到PP2正在使用的共享内存中,并在对它们执行caezar cipher后将这些字符保存到新文件中 它几乎可以工作,但我有点担心它不正确,因为它在sleep()存在时工作,没有它,synchronize就无法工作 文件tst包含文本: 大宗报价 szesnasciebajtow bajtowszesna

我不得不在linux上做一个关于同步和信号量的小项目,我遇到了一些麻烦。。。 问题是我想创建两个进程,子进程1(PP1)和子进程2(PP2),PP1按部分(16个字符)从文件中读取数据,并将它们保存到PP2正在使用的共享内存中,并在对它们执行caezar cipher后将这些字符保存到新文件中

它几乎可以工作,但我有点担心它不正确,因为它在sleep()存在时工作,没有它,synchronize就无法工作

文件tst包含文本:

大宗报价 szesnasciebajtow bajtowszesnascie Siaaaaallla

代码如下:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <err.h>
#include <errno.h>
#include <sys/mman.h> 
#include <fcntl.h>
#include <semaphore.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>

#define SHM_SIZE 16

int main()
{
    int countToCipher,character, rozmiar=0,rd,i,des;
    char nazwaPliku[50];

    printf("Type file name \n");
    scanf("%s", nazwaPliku);

    if( access( nazwaPliku, F_OK ) != -1 ) {
        printf("Type key number: \n");
        scanf("%i", &countToCipher);
    } else {
        printf("File does not exist!");
        exit(0);
    }

    if( access( nazwaPliku, R_OK ) == -1 ) {
        printf("No permission!");
        exit(0);
    }

    FILE* fodczyt;
    fodczyt = fopen(nazwaPliku, "r");
    fseek(fodczyt,0,SEEK_END);
    rozmiar = ftell(fodczyt);

    int shmid,semid;
    key_t key;
    char *shm,*s;       

    if ((key = ftok(".", 'B')) == -1) 
        errx(1, "Error key!");

    if ((shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0660)) < 0) {    
        perror("shmget");
        errx(2, "Error creatin shm!");
    }

    if ((shm = shmat(shmid, NULL, 0)) == (char *) -1){
        perror("shmat");
        errx(3, "Error connect shm");
    }               

    sem_t *sem1 = mmap(NULL, sizeof(*sem1),
                                PROT_READ | PROT_WRITE,                                                      
                                MAP_SHARED | MAP_ANONYMOUS, -1, 0);
    if (sem1 == MAP_FAILED) {
        perror("mmap");
        exit(EXIT_FAILURE);
    }

    sem_init(sem1, 1, 1);

    if(fork()==0){
        //PP1
        int stop = 0,i;
        FILE *odczyt = fopen(nazwaPliku, "r"); 
        char ch;

        while(stop!=1){
            printf("\nPP1 waits\n");
            sem_wait(sem1);
            printf("PP1 enter\n");

            s=shm;

            for(i=0;i<SHM_SIZE+1;i++){
                ch = getc(odczyt);
                if(feof(odczyt)){
                    stop=1;
                    s[i]=EOF;
                    int j;
                    for(j=0;j<SHM_SIZE-i;j++) s[i]='\0';
                    break;
                }
                s[i]=ch;                        
            }
            sem_post(sem1);
            printf("PP1 exit\n");
            sleep(2);
        }
        fclose(odczyt);
        shmdt(shm);
    }

    if(fork()==0){
        //PP2
        int stop=0;
        char* odbior;
        sleep(1);

        des = open( "szyfr", O_CREAT | O_WRONLY | O_APPEND,  0666 );
        while(stop!=1){
            printf("\nPP2 waits\n");
            sem_wait(sem1);
            printf("PP2 enter\n");

            odbior = shm;

            for (i = 0; i<SHM_SIZE; i++) {
                if(odbior[i]=='\0')
                {
                    stop=1;
                    break;
                }

                character = odbior[i];

                if (character >= 'a' && character <= 'z') {
                    character += (int)countToCipher;

                    if (character > 'z') {
                        character = character - 'z' + 'a' - 1;
                    }
                    odbior[i] = character;              
                }
                else if (character >= 'A' && character <= 'Z') {
                    character += (int)countToCipher;

                    if (character > 'z') {
                        character = character - 'A' + 'Z' - 1;
                    }
                    odbior[i] = character;
                }
            }
            write(des,odbior,SHM_SIZE);
            sem_post(sem1);
            printf("PP2 exit\n");
            sleep(2);
        }
        shmdt(shm);
        shmctl(shmid, IPC_RMID, NULL);
    }
    wait(NULL);
    wait(NULL);
    sem_destroy(sem1);

    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义SHM_尺寸16
int main()
{
int countToCipher,character,rozmiar=0,rd,i,des;
char nazwaPliku[50];
printf(“键入文件名\n”);
scanf(“%s”,nazwaPliku);
如果(访问(nazwaPliku,F_OK)!=-1){
printf(“键入键号:\n”);
scanf(“%i”和countToCipher);
}否则{
printf(“文件不存在!”);
出口(0);
}
如果(访问(nazwaPliku,R_OK)=-1){
printf(“不允许!”);
出口(0);
}
文件*fodczyt;
fodczyt=fopen(nazwaPliku,“r”);
fseek(fodczyt,0,SEEK_END);
rozmiar=ftell(fodczyt);
内特希米德,塞米德;
钥匙(t)钥匙;;
字符*shm,*s;
如果((键=ftok(“.”,'B'))=-1)
errx(1,“错误键!”);
如果((shmid=shmget(键,SHM_大小,IPC_创建| 0660))<0){
佩罗尔(“shmget”);
errx(2,“错误创建shm!”);
}
如果((shm=shmat(shmid,NULL,0))==(char*)-1){
佩罗尔(“shmat”);
errx(3,“错误连接shm”);
}               
sem_t*sem1=mmap(NULL,sizeof(*sem1),
保护读,保护写,
MAP|u SHARED | MAP|u ANONYMOUS,-1,0);
如果(sem1==MAP_失败){
佩罗尔(“mmap”);
退出(退出失败);
}
sem_init(sem1,1,1);
如果(fork()==0){
//PP1
int-stop=0,i;
文件*odczyt=fopen(nazwaPliku,“r”);
char ch;
while(停止!=1){
printf(“\nPP1等待\n”);
sem_wait(sem1);
printf(“PP1输入\n”);
s=shm;

对于(i=0;iI没有检查同步代码,但小写字符旋转的公式是错误的。此外,在大写部分,您正在检查
character>'z'
,而不是
character>'z'
。要测试同步,我建议尝试使用CountToChipher=0。在这种情况下,将使用相同的输入字符串好的,很好。老实说,我最关心这个同步,但是谢谢。