溫馨提示×

centos進程間如何同步

小樊
39
2025-08-10 17:58:44
欄目: 智能運維

在CentOS系統中,進程間同步可以通過多種機制實現,以下是一些常用的方法:

1. 文件鎖

文件鎖是一種簡單的進程間同步機制??梢允褂?code>fcntl系統調用或者fcntl命令來實現。

使用fcntl系統調用

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

int main() {
    int fd = open("lockfile.lock", O_RDWR | O_CREAT, 0666);
    if (fd == -1) {
        perror("open");
        exit(EXIT_FAILURE);
    }

    struct flock lock;
    lock.l_type = F_WRLCK; // 寫鎖
    lock.l_whence = SEEK_SET;
    lock.l_start = 0;
    lock.l_len = 0;

    if (fcntl(fd, F_SETLK, &lock) == -1) {
        perror("fcntl");
        close(fd);
        exit(EXIT_FAILURE);
    }

    // 執行臨界區代碼

    lock.l_type = F_UNLCK; // 解鎖
    if (fcntl(fd, F_SETLK, &lock) == -1) {
        perror("fcntl unlock");
    }

    close(fd);
    return 0;
}

使用fcntl命令

# 獲取鎖
fcntl -x lock -f lockfile.lock -u $$

# 釋放鎖
fcntl -x unlock -f lockfile.lock -u $$

2. 信號量

信號量是一種更高級的同步機制,可以使用System V信號量或者POSIX信號量。

使用System V信號量

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

union semun {
    int val;
    struct semid_ds *buf;
    unsigned short *array;
};

int main() {
    key_t key = ftok("semfile", 'a');
    int semid = semget(key, 1, IPC_CREAT | 0666);
    if (semid == -1) {
        perror("semget");
        exit(EXIT_FAILURE);
    }

    union semun arg;
    arg.val = 1; // 初始化信號量為1
    if (semctl(semid, 0, SETVAL, arg) == -1) {
        perror("semctl");
        exit(EXIT_FAILURE);
    }

    // 獲取信號量
    struct sembuf sb = {0, -1, SEM_UNDO};
    if (semop(semid, &sb, 1) == -1) {
        perror("semop");
        exit(EXIT_FAILURE);
    }

    // 執行臨界區代碼

    // 釋放信號量
    sb.sem_op = 1;
    if (semop(semid, &sb, 1) == -1) {
        perror("semop unlock");
        exit(EXIT_FAILURE);
    }

    semctl(semid, 0, IPC_RMID);
    return 0;
}

使用POSIX信號量

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#include <unistd.h>

int main() {
    sem_t *sem = sem_open("/mysem", O_CREAT, 0666, 1);
    if (sem == SEM_FAILED) {
        perror("sem_open");
        exit(EXIT_FAILURE);
    }

    // 獲取信號量
    if (sem_wait(sem) == -1) {
        perror("sem_wait");
        exit(EXIT_FAILURE);
    }

    // 執行臨界區代碼

    // 釋放信號量
    if (sem_post(sem) == -1) {
        perror("sem_post");
        exit(EXIT_FAILURE);
    }

    sem_close(sem);
    sem_unlink("/mysem");
    return 0;
}

3. 管道和消息隊列

管道和消息隊列也可以用于進程間同步。

使用管道

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
    int pipefd[2];
    if (pipe(pipefd) == -1) {
        perror("pipe");
        exit(EXIT_FAILURE);
    }

    pid_t pid = fork();
    if (pid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    if (pid == 0) { // 子進程
        close(pipefd[1]); // 關閉寫端
        char buffer[10];
        read(pipefd[0], buffer, sizeof(buffer));
        printf("Child received: %s\n", buffer);
        close(pipefd[0]);
    } else { // 父進程
        close(pipefd[0]); // 關閉讀端
        const char *message = "Hello from parent";
        write(pipefd[1], message, strlen(message) + 1);
        close(pipefd[1]);
    }

    return 0;
}

使用消息隊列

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>

struct msgbuf {
    long mtype;
    char mtext[100];
};

int main() {
    key_t key = ftok("msgfile", 'a');
    int msqid = msgget(key, IPC_CREAT | 0666);
    if (msqid == -1) {
        perror("msgget");
        exit(EXIT_FAILURE);
    }

    struct msgbuf msg;
    msg.mtype = 1;
    strcpy(msg.mtext, "Hello from sender");

    // 發送消息
    if (msgsnd(msqid, &msg, sizeof(msg.mtext), 0) == -1) {
        perror("msgsnd");
        exit(EXIT_FAILURE);
    }

    // 接收消息
    if (msgrcv(msqid, &msg, sizeof(msg.mtext), 1, 0) == -1) {
        perror("msgrcv");
        exit(EXIT_FAILURE);
    }

    printf("Received message: %s\n", msg.mtext);

    msgctl(msqid, IPC_RMID);
    return 0;
}

4. 共享內存

共享內存是一種高效的進程間通信方式,可以用于同步。

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>

int main() {
    key_t key = ftok("shmfile", 'a');
    int shmid = shmget(key, 1024, IPC_CREAT | 0666);
    if (shmid == -1) {
        perror("shmget");
        exit(EXIT_FAILURE);
    }

    char *str = (char *) shmat(shmid, NULL, 0);
    if (str == (char *) -1) {
        perror("shmat");
        exit(EXIT_FAILURE);
    }

    // 寫入數據
    strcpy(str, "Hello from shared memory");

    // 讀取數據
    printf("Read from shared memory: %s\n", str);

    shmdt(str);
    shmctl(shmid, IPC_RMID, NULL);
    return 0;
}

這些方法各有優缺點,選擇合適的同步機制取決于具體的應用場景和需求。

0
亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女