在C中处理与信号量的通信

时间:2016-08-29 13:26:33

标签: c synchronization ipc semaphore

我正在写两个文件: 带有父进程的father.c和带有子进程的son.c。他们应该使用信号量进行同步。当我启动父(已编译)时,父进程在子进程消息之后永远等待: 孩子用完了。

father.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

typedef union _semun {
    int val;
        struct semid_ds *buf;
        ushort *array; 
    }   semun;


int initsem(key_t key){
    int status = 0, semid;
    semid = semget(key, 1, 0600 | IPC_CREAT | IPC_EXCL);
    if(semid == -1){
        if(errno == EEXIST){
            semid = semget(key, 1, 0);
        }
    else{
        semun arg;
        arg.val = 1;
        status = semctl(semid, 0, SETVAL, arg);
    }
    if(semid == -1 || status == -1){
        perror("initsem failed\n");
        return -1;
    } 
    return (semid);
    }
}

int waitSem(int semid) {
    struct sembuf wait_buf;
    wait_buf.sem_num = 0;
    wait_buf.sem_op = -1;
    if(semop(semid, &wait_buf, 1) == -1) {
        perror("waitSem failed");
        exit(1);
    }
return(0);
}

int signalSem(int semid) {
    struct sembuf signal_buf;
    signal_buf.sem_num = 0;
    signal_buf.sem_op = 1;
    if(semop(semid, &signal_buf, 1) == -1) {
        perror("signalSem failed");
        exit(1);
    }
return(0);
}


int main(){

    pid_t pid;
    key_t key;

    int semid;

    if(key = ftok("/home/user/Scrivania/test.txt", 'a') == -1){
        perror("IPC error: ftok\n");
        exit(1);
    }
    else{
        printf("Ftok done\n");
    }

    semid = initsem(key);

    pid = fork();

    if(pid < 0){
        printf("failed fork()\n");
    }

    else if(pid == 0){
        printf("Child process with PID: %d\n", pid);
        execl("/home/user/Desktop/son", "son", "",(char *)0);
    }
    else{
        printf("Father process with PID: %d\n", pid);

        printf("Waiting for my son\n");
        waitSem(semid);
        printf("My son has done\n");
        signalSem(semid);



    }

    return 0;

}

son.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

typedef union _semun {
    int val;
        struct semid_ds *buf;
        ushort *array; 
    }   semun;


int initsem(key_t key){
    int status = 0, semid;
    semid = semget(key, 1, 0600 | IPC_EXCL);
    if(semid == -1){
        if(errno == EEXIST){
            semid = semget(key, 1, 0);
        }
    else{
        semun arg;
        arg.val = 1;
        status = semctl(semid, 0, SETVAL, arg);
    }
    if(semid == -1 || status == -1){
        perror("initsem failed\n");
        return -1;
    } 
    return (semid);
    }
}



int waitSem(int semid) {
    struct sembuf wait_buf;
    wait_buf.sem_num = 0;
    wait_buf.sem_op = -1;
    if(semop(semid, &wait_buf, 1) == -1) {
        perror("waitSem failed");
        exit(1);
    }
return(0);
}

int signalSem(int semid) {
    struct sembuf signal_buf;
    signal_buf.sem_num = 0;
    signal_buf.sem_op = 1;
    if(semop(semid, &signal_buf, 1) == -1) {
        perror("signalSem failed");
        exit(1);
    }
return(0);
}


int main(){

    pid_t pid;
    key_t key;

    int semid;




    if(key = ftok("/home/user/Desktop/test.txt", 'a') == -1){
        perror("IPC error: ftok\n");
        exit(1);
    }
    else{
        printf("Ftok done\n");
    }


        semid = initsem(key);
        waitSem(semid);     
        printf("Pre signal\n");
        signalSem(semid);
        printf("My operation\n");



    return 0;

}

0 个答案:

没有答案