当前位置: 首页 > news >正文

做网站需要什么准备搜索数据

做网站需要什么准备,搜索数据,手表网站 源码,久别的草原在线影院观看中文目录 一、无名管道 二、有名管道 三、共享内存 四、信号量 五、消息队列 六、套接字 一、无名管道 1.只能用于具有亲缘关系的进程之间的通信(也就是父子进程或者兄弟进程)。 2.是一个单工的通信模式,具有固定的读端和写端。 3.管道也可以看成是一种特殊的文件…

目录

一、无名管道

二、有名管道

三、共享内存

四、信号量

五、消息队列

六、套接字


一、无名管道

1.只能用于具有亲缘关系的进程之间的通信(也就是父子进程或者兄弟进程)。

2.是一个单工的通信模式,具有固定的读端和写端。

3.管道也可以看成是一种特殊的文件,对于它的读写也可以使用普通的read()、write()等函数。但是它不属于任何文件系统,并且只存在于内存中。

#include <unistd.h>
int pipe(int filedes[2]);
在管道中,文件描述符数组的第一个元素(索引为0)用于读取,第二个元素(索引为1)用于写入。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>#define BUFFER_SIZE 25
#define READ_END 0
#define WRITE_END 1int main() 
{char write_msg[BUFFER_SIZE] = "Hello, child!";char read_msg[BUFFER_SIZE];int fd[2];pid_t pid;// 创建管道if (pipe(fd) == -1) {fprintf(stderr, "Pipe failed");return 1;}// 创建子进程pid = fork();if (pid < 0) {fprintf(stderr, "Fork failed");return 1;}// 父进程if (pid > 0)   {// 关闭写入端,因为父进程不会写入close(fd[WRITE_END]);// 从管道中读取消息read(fd[READ_END], read_msg, BUFFER_SIZE);printf("Parent received message from child: %s\n", read_msg);// 关闭读取端close(fd[READ_END]);} // 子进程else {  // 关闭读取端,因为子进程不会读取close(fd[READ_END]);// 写入消息到管道write(fd[WRITE_END], write_msg, BUFFER_SIZE);// 关闭写入端close(fd[WRITE_END]);}return 0;
}

./a.out
执行结果:Parent received message from child: Hello, child! 

二、有名管道

  1. mkfifo(const char *pathname, mode_t mode):

    • 这个函数用于创建一个有名管道。
    • 参数pathname是要创建的管道的路径名,mode是指定管道权限的位掩码。
    • 返回值:成功时返回0,失败时返回-1,并设置errno变量表示错误类型。
  2. open(const char *pathname, int flags, mode_t mode):

    • 这个函数用于打开文件或管道。
    • 参数pathname是要打开的文件或管道的路径名,flags指定打开文件的方式(如只读、只写、读写等),mode是当创建新文件时指定的权限。
    • 返回值:成功时返回文件描述符,失败时返回-1,并设置errno变量表示错误类型。
  3. write(int fd, const void *buf, size_t count):

    • 这个函数用于向文件描述符指定的文件或管道中写入数据。
    • 参数fd是打开文件或管道时返回的文件描述符,buf是要写入的数据缓冲区,count是要写入的字节数。
    • 返回值:成功时返回实际写入的字节数,失败时返回-1,并设置errno变量表示错误类型。
  4. read(int fd, void *buf, size_t count):

    • 这个函数用于从文件描述符指定的文件或管道中读取数据。
    • 参数fd是打开文件或管道时返回的文件描述符,buf是用于接收数据的缓冲区,count是要读取的最大字节数。
    • 返回值:成功时返回实际读取的字节数,失败时返回-1,并设置errno变量表示错误类型。
  5. close(int fd):

    • 这个函数用于关闭打开的文件描述符。
    • 参数fd是要关闭的文件描述符。
    • 返回值:成功时返回0,失败时返回-1,并设置errno变量表示错误类型。
  6. unlink(const char *pathname):

    • 这个函数用于删除文件或链接。
    • 参数pathname是要删除的文件或链接的路径名。
    • 返回值:成功时返回0,失败时返回-1,并设置errno变量表示错误类型。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>#define BUFFER_SIZE 25int main() 
{char *fifo_name = "./name";char write_msg[BUFFER_SIZE] = "Hello, world!";char read_msg[BUFFER_SIZE];// 创建有名管道mkfifo(fifo_name, 0666);pid_t pid = fork();if (pid == 0)// 子进程负责写入{// 打开管道进行写入int fd_write = open(fifo_name, O_WRONLY);write(fd_write, write_msg, BUFFER_SIZE);close(fd_write);} else if (pid > 0) // 父进程负责读取{ // 打开管道进行读取int fd_read = open(fifo_name, O_RDONLY);read(fd_read, read_msg, BUFFER_SIZE);printf("Received message: %s\n", read_msg);close(fd_read);} else  // fork失败{fprintf(stderr, "Fork failed");return 1;}// 删除管道unlink(fifo_name);return 0;
}

三、共享内存

共享内存是最高效的,因为避免了数据在用户空间和内核空间的来回拷贝

  1. ftok(const char *pathname, int proj_id):

    • ftok()函数用于生成一个唯一的key,用于创建或访问共享内存。
    • 参数pathname是一个路径名,proj_id是一个整数,用于生成key。
    • 返回值:如果成功,返回一个唯一的key,如果失败,返回-1。
  2. shmget(key_t key, size_t size, int shmflg):

    • shmget()函数用于创建共享内存段或获取共享内存段的标识符。
    • 参数key是由ftok()生成的唯一key,size是共享内存的大小,shmflg是标志位,用于指定权限和行为。
    • 返回值:如果成功,返回共享内存段的标识符,如果失败,返回-1。
  3. shmat(int shmid, const void *shmaddr, int shmflg):

    • shmat()函数用于将共享内存连接到当前进程的地址空间。
    • 参数shmid是共享内存段的标识符,shmaddr通常为NULL(表示系统自动选择地址),shmflg是标志位,通常为0。
    • 返回值:如果成功,返回指向共享内存段的指针,如果失败,返回(void *)-1。
  4. shmdt(const void *shmaddr):

    • shmdt()函数用于将共享内存从当前进程的地址空间分离。
    • 参数shmaddr是指向共享内存段的指针。
    • 返回值:如果成功,返回0,如果失败,返回-1。
  5. shmctl(int shmid, int cmd, struct shmid_ds *buf):

    • shmctl()函数用于对共享内存进行控制操作,如删除共享内存段。
    • 参数shmid是共享内存段的标识符,cmd是控制命令,buf是一个指向shmid_ds结构体的指针,用于获取共享内存的状态信息。
    • 返回值:如果成功,返回0,如果失败,返回-1。

读端

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>#define SHM_SIZE 1024int main() 
{key_t key = ftok("/", 'R'); // 生成共享内存的key// 创建共享内存段int shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0666);if (shmid == -1) {perror("shmget");exit(1);}// 将共享内存连接到当前进程的地址空间char *shmaddr = shmat(shmid, NULL, 0);if (shmaddr == (void *)-1) {perror("shmat");exit(1);}// 写入数据到共享内存strcpy(shmaddr, "Hello, shared memory!");// 分离共享内存if (shmdt(shmaddr) == -1) {perror("shmdt");exit(1);}printf("数据已写入共享内存\n");return 0;
}

 写端

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>#define SHM_SIZE 1024int main() 
{key_t key = ftok("/", 'R'); // 生成共享内存的key// 获取共享内存段int shmid = shmget(key, SHM_SIZE, 0666);if (shmid == -1) {perror("shmget");exit(1);}// 将共享内存连接到当前进程的地址空间char *shmaddr = shmat(shmid, NULL, 0);if (shmaddr == (void *)-1){perror("shmat");exit(1);}printf("从共享内存中读取到的消息:%s\n", shmaddr);// 分离共享内存if (shmdt(shmaddr) == -1) {perror("shmdt");exit(1);}return 0;
}

写端执行后:

数据已写入共享内存

读端执行后:

从共享内存中读取到的消息:Hello, shared memory! 

四、信号量

1.信号量实现互斥

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>#define KEY 1234 // 信号量的键值// 定义一个联合体,用于semctl初始化
union semun {int val;struct semid_ds *buf;unsigned short *array;
};// 创建一个二值信号量并初始化为1
int create_semaphore() 
{// 创建一个信号量集,包含1个信号量int semid = semget(KEY, 1, IPC_CREAT | 0666); if (semid == -1) {perror("semget");exit(1);
}union semun arg;arg.val = 1; // 初始值为1,表示资源可用if (semctl(semid, 0, SETVAL, arg) == -1) // 初始化信号量{perror("semctl");exit(1);}return semid;
}// P操作(等待资源)
void P(int semid) 
{struct sembuf op;op.sem_num = 0; // 信号量集中的第一个信号量op.sem_op = -1; // 对信号量执行P操作op.sem_flg = 0;if (semop(semid, &op, 1) == -1) {perror("semop");exit(1);}
}// V操作(释放资源)
void V(int semid) 
{struct sembuf op;op.sem_num = 0; // 信号量集中的第一个信号量op.sem_op = 1; // 对信号量执行V操作op.sem_flg = 0;if (semop(semid, &op, 1) == -1) {perror("semop");exit(1);}
}int main()
{int semid = create_semaphore(); // 创建信号量pid_t pid = fork(); // 创建子进程if (pid == -1) {perror("fork");exit(1);}if (pid == 0)  // 子进程{P(semid); // 等待资源printf("Child process: Counter decremented by 1.\n");V(semid); // 释放资源} else // 父进程{sleep(1); // 让子进程有机会先运行P(semid); // 等待资源printf("Parent process: Counter incremented by 1.\n");V(semid); // 释放资源}return 0;
}
  1. semget(key_t key, int nsems, int semflg)

    • 这个函数用于创建一个新的信号量集或获取一个现有信号量集的标识符。
    • key是一个用于唯一标识信号量集的键值。
    • nsems指定了信号量集中的信号量数量。
    • semflg是一组标志,用于指定创建信号量集的权限和行为。
    • 返回值:成功时返回信号量集的标识符,失败时返回-1。
  2. semctl(int semid, int semnum, int cmd, union semun arg)

    • 这个函数用于对信号量集进行控制操作,如初始化、设置值、获取值等。
    • semid是信号量集的标识符。
    • semnum是指定的信号量在集合中的索引,通常为0。
    • cmd是指定要执行的控制命令。
    • arg是一个联合体,用于传递控制命令的参数。
    • 返回值:根据控制命令不同而不同。
  3. semop(int semid, struct sembuf *sops, size_t nsops)

    • 这个函数用于执行一组信号量操作,如等待资源(P操作)和释放资源(V操作)。
    • semid是信号量集的标识符。
    • sops是一个指向信号量操作结构体数组的指针。
    • nsops是指定的信号量操作结构体数组的大小。
    • 返回值:成功时返回0,失败时返回-1。
  4. struct sembuf

    • 这是一个结构体,用于描述信号量操作。
    • 它包含了三个字段:
      • sem_num:信号量集中的信号量索引。
      • sem_op:信号量操作,通常是-1(P操作,等待资源)或1(V操作,释放资源)。
      • sem_flg:信号量操作的标志位,通常为0。
  5. union semun

    • 这是一个联合体,用于传递给semctl()函数的参数。
    • 它包含了多个字段,其中的一个字段可以根据不同的控制命令来使用,比如用于设置或获取信号量值时使用的val字段,用于获取信号量状态信息时使用的buf字段等

  1. create_semaphore():

    • 这个函数用于创建一个二值信号量,并将其初始化为1。
    • 首先,它调用 semget() 函数创建一个包含一个信号量的信号量集,如果创建失败则会打印错误信息并退出程序。
    • 然后,它使用 semctl() 函数将信号量的值初始化为1,表示资源可用。
    • 最后,它返回创建的信号量集的标识符。
  2. P(int semid):

    • 这个函数用于执行 P 操作,即等待资源。
    • 首先,它定义了一个 struct sembuf 结构体 op,用于描述信号量操作。
    • 然后,它将 op.sem_num 设置为0,表示信号量集中的第一个信号量。
    • 接着,它将 op.sem_op 设置为-1,表示对信号量执行 P 操作。
    • 最后,它调用 semop() 函数执行信号量操作,如果操作失败则会打印错误信息并退出程序。
  3. V(int semid):

    • 这个函数用于执行 V 操作,即释放资源。
    • 它的实现与 P() 函数类似,只是将 op.sem_op 设置为1,表示对信号量执行 V 操作。

2.信号量实现同步互斥 

交替实现奇偶数打印,打印一个奇数后必须是一个偶数

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>#define KEY 1234 // 信号量的键值// 定义一个联合体,用于semctl初始化
union semun {int val;struct semid_ds *buf;unsigned short *array;
};// 创建一个信号量并初始化为1
int create_semaphore() 
{int semid = semget(KEY, 1, IPC_CREAT | 0666); // 创建一个信号量集,包含1个信号量if (semid == -1) {perror("semget");exit(1);}union semun arg;arg.val = 0; // 初始值为0if (semctl(semid, 0, SETVAL, arg) == -1) // 初始化信号量{ perror("semctl");exit(1);}return semid;
}// P操作(等待资源)
void P(int semid) 
{struct sembuf op;op.sem_num = 0; // 信号量集中的第一个信号量op.sem_op = -1; // 对信号量执行P操作op.sem_flg = 0;if (semop(semid, &op, 1) == -1) {perror("semop");exit(1);}
}// V操作(释放资源)
void V(int semid) 
{struct sembuf op;op.sem_num = 0; // 信号量集中的第一个信号量op.sem_op = 1; // 对信号量执行V操作op.sem_flg = 0;if (semop(semid, &op, 1) == -1) {perror("semop");exit(1);}
}int main() 
{int  i = 1;int j = 2;int semid = create_semaphore(); // 创建信号量pid_t pid = fork(); // 创建子进程if (pid == -1) {perror("fork");exit(1);}if (pid == 0)  // 子进程打印奇数{while(1){ 		printf("i = %d\n",i);i += 2;V(semid); // 释放资源sleep(1);}       } else // 父进程打印偶数{while(1){P(semid); // 等待资源printf("j = %d\n",j);j += 2;}		}return 0;
}

执行结果

i = 1
j = 2
i = 3
j = 4
i = 5
j = 6
i = 7
j = 8
i = 9
j = 10
i = 11
j = 12
i = 13
j = 14
i = 15
j = 16
 

五、消息队列

发送进程

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>#define MSG_KEY 1234 // 消息队列的键值// 定义消息结构体
struct msg_buffer 
{long msg_type; // 消息类型char msg_text[100]; // 消息内容
};int main() 
{int msgid;struct msg_buffer message_send;// 创建消息队列msgid = msgget(MSG_KEY, IPC_CREAT | 0666);if (msgid == -1) {perror("msgget");exit(1);}// 准备发送的消息strcpy(message_send.msg_text, "Hello, Message Queue!");message_send.msg_type = 1; // 消息类型为1// 发送消息if (msgsnd(msgid, &message_send, sizeof(message_send) - sizeof(long), 0) == -1) {perror("msgsnd");exit(1);}printf("Parent process sent message: %s\n", message_send.msg_text);return 0;
}

 接收进程

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>#define MSG_KEY 1234 // 消息队列的键值// 定义消息结构体
struct msg_buffer {long msg_type; // 消息类型char msg_text[100]; // 消息内容
};int main() 
{int msgid;struct msg_buffer message_rcv;// 创建消息队列msgid = msgget(MSG_KEY, IPC_CREAT | 0666);if (msgid == -1) {perror("msgget");exit(1);}// 接收消息if (msgrcv(msgid, &message_rcv, sizeof(message_rcv) - sizeof(long), 1, 0) == -1) {perror("msgrcv");exit(1);}printf("Child process received message: %s\n", message_rcv.msg_text);return 0;
}

执行结果:

./s

Parent process sent message: Hello, Message Queue!
./r
Child process received message: Hello, Message Queue!
 

在这两个示例代码中,主要使用了以下系统调用:

  1. msgget: 用于创建或打开一个消息队列。它接受一个参数,即消息队列的键值(一个唯一的标识符),并返回一个消息队列的标识符(msgid)。

  2. msgsnd: 用于向消息队列发送消息。它接受四个参数:消息队列的标识符(msgid)、指向要发送的消息的指针、消息的大小(不包括消息类型字段的大小)、消息的标志(通常为0)。

  3. msgrcv: 用于从消息队列接收消息。它接受五个参数:消息队列的标识符(msgid)、指向用于接收消息的缓冲区的指针、缓冲区大小(不包括消息类型字段的大小)、消息类型(通常为正整数)、接收消息的标志(通常为0)。

  4. msgctl: 用于控制消息队列的属性,如删除消息队列。在这个示例中,我们使用它来删除消息队列。它接受三个参数:消息队列的标识符(msgid)、命令(IPC_RMID 表示删除消息队列)、指向用于控制消息队列属性的结构体的指针(在这个例子中不需要)。

六、套接字

网络部分的内容

http://www.zhongyajixie.com/news/23378.html

相关文章:

  • 做网站 你的出路在哪里百度快快速排名
  • 衡水教育行业网站建设关键词筛选工具
  • 360网站建设公司哪家好护肤品软文推广
  • 网站建设分类杭州旺道企业服务有限公司
  • 上传网站信息问题什么是网站推广策略
  • 杭州做网站价格网络营销的内容有哪些方面
  • 网站建设珠海 新盈科技公司网站外链优化方法
  • 河南濮阳建设局网站网站seo推广平台
  • mamp安装wordpress北京百度seo关键词优化
  • wordpress金融百度seo排名技术必不可少
  • 专业的深圳网站设计友缘在线官网
  • 网站建设 开发谷歌chrome浏览器官方下载
  • 网站切换图片做背景怎么写珠海网络推广公司
  • 台州优秀网站设计有什么引流客源的软件
  • 政府 网站建设方案学生没钱怎么开网店
  • 山西正规网站建设推广今日新闻头条最新消息
  • 可以做四级的网站网站快速搜索
  • 图片网站怎么做优化重庆seo
  • 甘肃网站制作公司短视频seo排名系统
  • 网站开发语言怎么选网络营销的方法有哪些?举例说明
  • akcms做的网站推广管理
  • 网站的seo方案怎么做竞价sem托管公司
  • 线上企业订单管理系统网站做个网站
  • 哪个网站发布招聘信息免费网站优化查询
  • 512 做网站广州优化疫情防控措施
  • 深圳汽车网站建设seo排名点击首页
  • 新手如何学做网站全国十大跨境电商排名
  • 免费的网站模板关键词网站
  • 政府网站建设原则百度竞价关键词价格查询工具
  • 河北省建设工程质量监督网站深圳网站推广