5

I'm just playing with some GCD functions for writing and reading data to files. Two of these functions are dispatch_write() and dispatch_read(), which allow one to write and read data to a file descriptor without having to setup a new dispatch_io_t channel.

So, I have the following code:

#import <dispatch/dispatch.h>
#import <stdio.h>
#import <unistd.h>

int main() {
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    int intbuffer[] = { 1, 2, 3, 4 };
    dispatch_data_t data = dispatch_data_create(intbuffer, 4 * sizeof(int), queue, NULL);

    // Write
    dispatch_fd_t fd = open("data.dat", O_RDWR);
    printf("FD: %d\n", fd);

    dispatch_write(fd, data, queue,^(dispatch_data_t d, int e) {
        printf("Written %zu bytes!\n", dispatch_data_get_size(d));
        printf("\tError: %d\n", e);
    });

    close(fd);

    // Read
    fd = open("data.dat", O_RDWR);

    dispatch_read(fd, 4 * sizeof(int), queue, ^(dispatch_data_t d, int e) {
        printf("Read %zu bytes!\n", dispatch_data_get_size(d));
        printf("\tError: %d\n", e);
    });

    close(fd);

    // Exit confirmation
    getchar();

    return 0;
}

with which I'm attempting to write a 4-integer array to a file and, after that, to read it back. I previously created data.dat with the touch command and anyone has full access to it (sudo chmod 777 data.dat).

When I execute this code, it seems data.dat gets open successfully, since the program prints out FD: 3, which is a valid file descriptor, but dispatch_write doesn't write anything to it, since I get:

Written 0 bytes!
    Error: 9
Read 0 bytes!
    Error: 9

Error 9 is the code for a EBADF error, but, again, 3 is a valid file descriptor.

So, what am I doing wrong?

4

1 回答 1

7

dispatch_read并且dispatch_write不是同步调用——这就是它们的全部意义所在。换句话说,您在这里设置它的方式,close就是在调用dispatch_write. 当 GCD 在后台线程上执行写入时,文件描述符已经关闭。读取操作也一样。在关闭文件之前,您必须等到写操作完成。

我对您的代码进行了一些修改dispatch_semaphore,以便在关闭文件之前使用 a 等待写入和读取完成:

int main() {
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    int intbuffer[] = { 1, 2, 3, 4 };
    dispatch_data_t data = dispatch_data_create(intbuffer, 4 * sizeof(int), queue, NULL);

    dispatch_semaphore_t sem = dispatch_semaphore_create(0);
    // Write
    dispatch_fd_t fd = open("/tmp/data.dat", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO);

    printf("FD: %d\n", fd);

    dispatch_write(fd, data, queue,^(dispatch_data_t d, int e) {
        printf("Written %zu bytes!\n", dispatch_data_get_size(data) - (d ? dispatch_data_get_size(d) : 0));
        printf("\tError: %d\n", e);
        dispatch_semaphore_signal(sem);
    });

    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);

    close(fd);

    // Read
    fd = open("/tmp/data.dat", O_RDWR);

    dispatch_read(fd, 4 * sizeof(int), queue, ^(dispatch_data_t d, int e) {
        printf("Read %zu bytes!\n", dispatch_data_get_size(d));
        printf("\tError: %d\n", e);
        dispatch_semaphore_signal(sem);
    });

    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
    close(fd);

    // Exit confirmation
    getchar();

    return 0;
}
于 2013-07-31T12:50:27.770 回答