1. semget创建/获取信号量
2. semop操作信号量,pv
3. semctl执行型号量命令,设置值、获取值、删除信号量等
锁一般用于线程间通信,进程间通信可以用信号量。还有其他的共享内存,消息队列,socket,管道等
模拟写了一个类似消费者/生产模式,消费者进程释放信号量,生产者进程获取信号量
// // Created by gxf on 2020/2/23. // #ifndef UNTITLED_SEM_DEMO_H #define UNTITLED_SEM_DEMO_H extern char *ftokFilePath; extern int projId; extern int semId; int initSem(); int semP(); int semV(); int delSem(); #endif //UNTITLED_SEM_DEMO_H
// // Created by gxf on 2020/2/23. // #include "sem-demo.h" #include <unistd.h> #include <sys/ipc.h> #include <sys/sem.h> #include <stdlib.h> #include <stdio.h> int semId; char *ftokFilePath = "/Users/gxf/CLionProjects/untitled/tmp_sem_demo"; int projId = 1; int initSem() { key_t ftokRes = ftok(ftokFilePath, projId); // get sem semId = semget(ftokRes, 1, IPC_CREAT | 0660); if (semId == -1) { perror("semget fail"); return -1; } // init sem num 1 union semun semunArg; semunArg.val = 1; int funRes = semctl(semId, 0, SETVAL, semunArg); if (funRes) { perror("semctl fail"); return -1; } return 0; } int semP() { struct sembuf sembufVal; sembufVal.sem_num = 0; sembufVal.sem_op = -1; sembufVal.sem_flg = 0; int res = semop(semId, &sembufVal, 1); if (res) { perror("semop fail"); return -1; } return 0; } int semV() { struct sembuf sembufVal; sembufVal.sem_op = 1; sembufVal.sem_num = 0; int res = semop(semId, &sembufVal, 1); if (res) { perror("semop fail"); return -1; } return 0; } int delSem() { union semun semunVal; semId = 65544; int res = semctl(semId, 0, IPC_RMID, semunVal); if (res) { perror("semctl rmid fail"); return -1; } return 1; }
// // Created by gxf on 2020/2/23. // #include <stdio.h> #include <stdlib.h> #include "sem-demo.h" #include <unistd.h> int main() { initSem(); while (1) { if (semV()) { printf("comsumer v fail\n"); } printf("consumer\n"); sleep(1); } return 0; }
// // Created by gxf on 2020/2/23. // #include <stdio.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/sem.h> #include <unistd.h> #include "sem-demo.h" #include <pthread.h> void produce(); int main() { // delSem(); initSem(); pthread_t threads[10]; for (int i = 0; i < 10; i++) { pthread_create(&threads[i], NULL, produce, NULL); } for (int i = 0; i < 10;i++) { pthread_join(threads[i], NULL); } return 0; } void produce() { while (1) { printf("producer tid:%d\n", pthread_self()); semP(); // sleep(3); } }