当前位置: 首页> 娱乐> 八卦 > word模板免费下载素材_企业展厅设计公司哪家好怎么样_关键词指数查询_下载百度极速版

word模板免费下载素材_企业展厅设计公司哪家好怎么样_关键词指数查询_下载百度极速版

时间:2025/7/11 23:51:02来源:https://blog.csdn.net/m0_66405876/article/details/146810893 浏览次数:0次
word模板免费下载素材_企业展厅设计公司哪家好怎么样_关键词指数查询_下载百度极速版

一. 消息队列

1.1 发送端

  1. 申请 Key

  2. 打开/创建消息队列msgget

  3. 向消息队列发送消息msgsnd

1.2 接收端

  1. 打开/创建消息队列msgget

  2. 从消息队列接收消息msgrcv

  3. 控制(删除)消息队列msgctl


1.3 打开/创建消息队列

#include <sys/ipc.h>
#include <sys/msg.h>
​
int msgget(key_t key, int msgflg);

1.3.1 参数说明

  • key:和消息队列关联的 key,可使用 IPC_PRIVATEftok 生成。

  • msgflg:标志位,通常为 IPC_CREAT | 0666

    • IPC_CREAT:若消息队列不存在则创建,存在则打开。

1.3.2 返回值

  • 成功:返回消息队列的 ID。

  • 失败:返回 -1。

1.3.3 示例代码

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
​
int main() {key_t key = ftok("msgqueue", 'a'); // 生成 keyif (key == -1) {perror("ftok failed");return 1;}
​int msgid = msgget(key, IPC_CREAT | 0666); // 打开/创建消息队列if (msgid == -1) {perror("msgget failed");return 1;}
​printf("消息队列已创建,ID: %d\n", msgid);return 0;
}

1.4 发送消息

#include <sys/ipc.h>
#include <sys/msg.h>
​
int msgsnd(int msgqid, const void *msgp, size_t size, int msgflg);

1.4.1 参数说明

  • msgqid:消息队列 ID。

  • msgp:消息缓冲区地址。

  • size:消息正文长度。

  • msgflg:标志位,可为 0IPC_NOWAIT

    • 0:消息队列满时阻塞,直到消息写入。

    • IPC_NOWAIT:消息队列满时立即返回。

1.4.2 返回值

  • 成功:返回 0。

  • 失败:返回 -1。

1.4.3 示例代码

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
​
typedef struct {long msg_type; // 消息类型char buf[128]; // 消息内容
} msgT;
​
int main() {key_t key = ftok("msgqueue", 'a'); // 生成 keyif (key == -1) {perror("ftok failed");return 1;}
​int msgid = msgget(key, IPC_CREAT | 0666); // 打开/创建消息队列if (msgid == -1) {perror("msgget failed");return 1;}
​msgT msg;msg.msg_type = 1;strcpy(msg.buf, "你好,这是消息队列发送的消息!");
​if (msgsnd(msgid, &msg, sizeof(msg.buf), 0) == -1) {perror("msgsnd failed");return 1;}
​printf("消息已发送到消息队列\n");return 0;
}

1.5 消息格式

typedef struct {long msg_type; // 消息类型char buf[128]; // 消息内容
} msgT;

1.5.1 注意事项

  1. 消息结构必须包含 long 类型的 msg_type 字段。

  2. 消息长度不包括 msg_type 的长度。


1.6 消息的接收

#include <sys/ipc.h>
#include <sys/msg.h>
​
int msgrcv(int msgqid, void *msgp, size_t size, long msgtype, int msgflg);

1.6.1 参数说明

  • msgqid:消息队列 ID。

  • msgp:消息缓冲区地址。

  • size:指定接收的消息长度。

  • msgtype:指定接收的消息类型。

    • msgtype=0:接收第一条消息,任意类型。

    • msgtype>0:接收第一条指定类型的消息。

    • msgtype<0:接收类型小于等于绝对值的消息。

  • msgflg:标志位。

    • 0:阻塞式接收。

    • IPC_NOWAIT:如果没有返回条件的消息立即返回,此时错误码为 ENOMSG

    • IPC_EXCEPT:与 msgtype 配合使用返回队列中第一个类型不为 msgtype 的消息。

1.6.2 返回值

  • 成功:返回收到的消息长度。

  • 失败:返回 -1。

1.6.3 示例代码

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <string.h>
​
typedef struct {long msg_type; // 消息类型char buf[128]; // 消息内容
} msgT;
​
int main() {key_t key = ftok("msgqueue", 'a'); // 生成 keyif (key == -1) {perror("ftok failed");return 1;}
​int msgid = msgget(key, IPC_CREAT | 0666); // 打开/创建消息队列if (msgid == -1) {perror("msgget failed");return 1;}
​msgT msg;if (msgrcv(msgid, &msg, sizeof(msg.buf), 1, 0) == -1) {perror("msgrcv failed");return 1;}
​printf("收到消息:类型=%ld,内容=%s\n", msg.msg_type, msg.buf);return 0;
}

1.7 消息队列的控制

#include <sys/ipc.h>
#include <sys/msg.h>
​
int msgctl(int msgqid, int cmd, struct msqid_ds *buf);

1.7.1 参数说明

  • msgqid:消息队列 ID。

  • cmd:要执行的操作。

    • IPC_STAT:获取消息队列状态。

    • IPC_SET:设置消息队列权限。

    • IPC_RMID:删除消息队列。

  • buf:存放消息队列属性的地址。

1.7.2 返回值

  • 成功:返回 0。

  • 失败:返回 -1。

1.7.3 示例代码

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>int main() {key_t key = ftok("msgqueue", 'a'); // 生成 keyif (key == -1) {perror("ftok failed");return 1;}int msgid = msgget(key, IPC_CREAT | 0666); // 打开/创建消息队列if (msgid == -1) {perror("msgget failed");return 1;}// 删除消息队列if (msgctl(msgid, IPC_RMID, NULL) == -1) {perror("msgctl failed");return 1;}printf("消息队列已删除\n");return 0;
}
二、信号灯/信号量(semaphore)

2.1 概念

信号灯是不同进程间或一个进程内部不同线程间同步的机制。类似我们的 PV 操作,适用于生产者和消费者场景。

2.1.1 PV 操作

  • P(S):申请资源。

    • 若信号量值大于 0,则减 1 并继续运行。

    • 若信号量值为 0,则任务阻塞。

  • V(S):释放资源。

    • 信号量值加 1。

    • 若有任务等待资源,则唤醒一个任务。


2.2 三种信号灯

  1. Posix 有名信号灯

  2. Posix 无名信号灯(Linux 只支持线程同步)

  3. System V 信号灯


2.3 有名信号灯

2.3.1 打开

sem_t *sem_open(const char *name, int oflag);
sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);
2.3.1.1 参数说明
  • name:信号灯的名字。

  • oflag:打开方式,常用 O_CREAT

  • mode:文件权限,常用 0666

  • value:信号量值,二元信号灯值为 1。

2.3.2 关闭

int sem_close(sem_t *sem);

2.3.3 删除

int sem_unlink(const char *name);

2.3.4 示例代码

#include <stdio.h>
#include <semaphore.h>
#include <fcntl.h>
#include <unistd.h>int main() {sem_t *sem = sem_open("mysem", O_CREAT, 0666, 1); // 打开信号灯if (sem == SEM_FAILED) {perror("sem_open failed");return 1;}// 使用信号灯...if (sem_close(sem) == -1) {perror("sem_close failed");return 1;}if (sem_unlink("mysem") == -1) {perror("sem_unlink failed");return 1;}printf("信号灯已创建并删除\n");return 0;
}

2.4 无名信号灯

2.4.1 初始化

int sem_init(sem_t *sem, int shared, unsigned int value);
2.4.1.1 参数说明
  • sem:需要初始化的信号灯变量。

  • shared:指定为 0,表示信号量只能由初始化进程使用。

  • value:信号量值。

2.4.2 销毁

int sem_destroy(sem_t *sem);

2.4.3 示例代码

#include <stdio.h>
#include <semaphore.h>
#include <unistd.h>int main() {sem_t sem;if (sem_init(&sem, 0, 1) == -1) { // 初始化信号灯perror("sem_init failed");return 1;}// 使用信号灯...if (sem_destroy(&sem) == -1) {perror("sem_destroy failed");return 1;}printf("无名信号灯已初始化并销毁\n");return 0;
}

2.5 信号灯操作

2.5.1 P 操作(获取资源)

int sem_wait(sem_t *sem);
  • 若信号量为 0,调用线程挂起,直到有空闲资源。

2.5.2 V 操作(释放资源)

int sem_post(sem_t *sem);
  • 若无等待线程,信号量值加 1。

  • 若有等待线程,唤醒一个线程。

2.5.3 示例代码

#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>
#include <unistd.h>sem_t sem;void *thread_function(void *arg) {printf("线程等待信号...\n");sem_wait(&sem); // P 操作printf("线程收到信号,继续执行...\n");return NULL;
}int main() {if (sem_init(&sem, 0, 0) == -1) { // 初始化信号灯perror("sem_init failed");return 1;}pthread_t thread;pthread_create(&thread, NULL, thread_function, NULL);sleep(1); // 主线程等待printf("主线程发送信号...\n");sem_post(&sem); // V 操作pthread_join(thread, NULL);sem_destroy(&sem);return 0;
}

2.6 System V 信号灯

2.6.1 创建/打开

int semget(key_t key, int nsems, int semflg);
2.6.1.1 参数说明
  • keyftok 生成的 key 值。

  • nsems:信号灯数目。

  • semflg:访问权限,常用 IPC_CREAT | 0666

2.6.1.2 返回值
  • 成功:返回信号灯集 ID。

  • 失败:返回 -1。

2.6.2 操作

int semop(int semid, struct sembuf *ops, size_t nops);
2.6.2.1 参数说明
  • semid:信号灯集 ID。

  • ops:操作数组。

  • nops:操作数目。

2.6.2.2 结构体 sembuf
struct sembuf {short sem_num; // 要操作的信号灯的编号short sem_op;  // 1:释放资源,V 操作;-1:分配资源,P 操作short sem_flg; // 0(阻塞), IPC_NOWAIT, SEM_UNDO
};

2.6.3 示例代码

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>int main() {key_t key = ftok("semaphore", 'a'); // 生成 keyif (key == -1) {perror("ftok failed");return 1;}int semid = semget(key, 1, IPC_CREAT | 0666); // 创建信号灯if (semid == -1) {perror("semget failed");return 1;}struct sembuf sops;sops.sem_num = 0;sops.sem_op = -1; // P 操作sops.sem_flg = 0;if (semop(semid, &sops, 1) == -1) {perror("semop failed");return 1;}printf("信号灯 P 操作成功\n");sops.sem_op = 1; // V 操作if (semop(semid, &sops, 1) == -1) {perror("semop failed");return 1;}printf("信号灯 V 操作成功\n");// 删除信号灯if (semctl(semid, 0, IPC_RMID) == -1) {perror("semctl failed");return 1;}printf("信号灯已删除\n");return 0;
}


关键字:word模板免费下载素材_企业展厅设计公司哪家好怎么样_关键词指数查询_下载百度极速版

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: