apue 习题4.6参考答案

#include "apue.h"
#include "myerr.h"
#include <unistd.h>
#include <fcntl.h>

int 
main(int argc, char *argv[])
{   
    if(argc != 3)
        err_sys("usage: ./EX_4_6.o <src path> <dst path>"); 

    char *src_path = argv[1];
    char *dst_path = argv[2];

    int fd = open(src_path, O_RDWR);
    int fd2 = open(dst_path, O_WRONLY); 

    int n;
    char buf[100] = "1234567890123456789";
    char buf2;  

    /* 给源文件制造空洞,结束后将源文件偏移量设为0 */

    int offset = lseek(fd, 100, SEEK_SET);
    printf("offset of src is %d\n", offset);
    printf("the buf is %s\n", buf);
    if(write(fd, buf, 100) < 0)
        err_sys("write to source file error.");
    lseek(fd, 0, SEEK_SET);

    /* 将源文件内容复制到目标文件 */
    while((n = read(fd, &buf2, 1)) == 1)
    {
        /* 如果读到'\0',则不复制 */
        if(buf2 == '\0')
            continue;
        if(write(fd2, &buf2, 1) != 1)
            err_sys("write error.");
    }

    if(n < 0)
        err_sys("read error.");

    close(fd);
    close(fd2);
    exit(0);
}

  运行此段代码得到的源文件和目标文件的内容如下:
  

/* source */
xxx@xxx:~/Desktop/apue_demo/file_dir$ od -c foo 
0000000   1   2   3   3   4   5   5  \n  \0  \0  \0  \0  \0  \0  \0  \0
0000020  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
*
0000140  \0  \0  \0  \0   1   2   3   4   5   6   7   8   9   0   1   2
0000160   3   4   5   6   7   8   9  \0  \0  \0  \0  \0  \0  \0  \0  \0
0000200  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
*
0000300  \0  \0  \0  \0  \0  \0  \0  \0
0000310
/* dest */
xxx@xxx:~/Desktop/apue_demo/file_dir$ od -c bar
0000000   1   2   3   3   4   5   5  \n   1   2   3   4   5   6   7   8
0000020   9   0   1   2   3   4   5   6   7   8   9
0000033
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
习题 9.2: 编写一个程序,创建一个共享内存区,然后将一个文件映射到该共享区中。编写两个程序,一个程序将数据写到共享区中,另一个程序读取共享区中的数据,并将结果写到标准输出。使用信号量进行同步。 解答: 以下是一个简单的实现: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/shm.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/mman.h> #include <semaphore.h> #define SHM_SIZE 1024 // 共享内存区大小 #define SEM_NAME "/mysem" // 信号量名称 int main(int argc, char *argv[]) { int shm_fd; void *shm_ptr; sem_t *sem_ptr; int value = 0; // 创建共享内存区 shm_fd = shm_open("myshm", O_CREAT | O_RDWR, 0666); ftruncate(shm_fd, SHM_SIZE); // 映射共享内存区 shm_ptr = mmap(NULL, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); // 创建信号量 sem_ptr = sem_open(SEM_NAME, O_CREAT, 0666, 1); // 写入数据 sem_wait(sem_ptr); // 申请信号量 sprintf(shm_ptr, "%s", "Hello, world!"); sem_post(sem_ptr); // 释放信号量 // 读取数据 sem_wait(sem_ptr); // 申请信号量 printf("%s\n", (char*)shm_ptr); sem_post(sem_ptr); // 释放信号量 // 销毁信号量 sem_close(sem_ptr); sem_unlink(SEM_NAME); // 解除共享内存区映射 munmap(shm_ptr, SHM_SIZE); // 销毁共享内存区 shm_unlink("myshm"); return 0; } ``` 在这个程序中,我们使用 `shm_open` 和 `ftruncate` 函数创建了一个大小为 `SHM_SIZE` 的共享内存区,并使用 `mmap` 函数将其映射到进程的地址空间中。然后,我们使用 `sem_open` 函数创建了一个信号量,并在写入数据和读取数据的过程中使用 `sem_wait` 和 `sem_post` 函数进行同步。最后,我们使用 `munmap` 函数解除了共享内存区的映射,并使用 `shm_unlink` 函数销毁了共享内存区。 编写第二个程序时,只需要将写入数据和读取数据的顺序颠倒即可。同时,需要使用相同的共享内存区和信号量名称。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值