如何在管道文件描述符的线程块中创建 read()?
how to make read() in thread block on a pipe's file descriptor?
我正在试验如何在 C 中的线程和主函数之间进行通信
以下代码中存在我不理解的行为:
#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
void* output(void* pipe1);
int main(int argc, const char *argv[])
{
pthread_t tid0;
int pipe1[2];
char buffer[200];
// Creating the pipe
pipe(pipe1);
// Creating the thread and passing the pipe as argument
pthread_create(&tid0, NULL, output, &pipe1);
// Input from user
scanf("%s", buffer);
// Writing to the pipe
write(pipe1[1], buffer, strlen(buffer));
return 0;
}
void* output(void* pipe1) {
char buffer[200];
// Reading the pipe and print the buffer
read(((int*)pipe1)[0], buffer, strlen(buffer));
printf("thread say: %s\n", buffer);
pthread_exit(NULL);
}
为什么读取函数不会阻塞管道的文件描述符?
也许我应该关闭管道的末端,但由于它们共享相同的内存space,当我调用读取或写入时返回错误"bad file descriptor"。
如果管道确实是一个糟糕的解决方案,也许你可以指导我使用其他方法(举个例子,它会很棒!:))
非常感谢!
编辑:解决方案
非常感谢您的回答,这里是具有预期行为的代码
#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
void* output(void* pipe1);
int main(int argc, const char *argv[])
{
pthread_t tid0;
int pipe1[2];
char buffer[200];
// Creating the pipe
pipe(pipe1);
// Creating the thread and passing the pipe as argument
pthread_create(&tid0, NULL, output, &pipe1);
// Input from user
scanf("%s", buffer);
// Writing to the pipe
if (write(pipe1[1], buffer, strlen(buffer)) < 0) {
perror("write");
exit(1);
}
// join so the main "wait" for the thread
pthread_join(tid0, NULL);
return 0;
}
void* output(void* pipe1) {
char buffer[200];
int nread;
// Reading the pipe and print the buffer
nread = read(((int*)pipe1)[0], buffer, sizeof buffer - 1);
if (nread < 0) {
fprintf(stderr, "ERROR\n");
perror("read");
exit(1);
}
buffer[nread] = '[=11=]';
fprintf(stderr, "thread say: %s\n", buffer);
pthread_exit(NULL);
}
char buffer[200];
read(((int*)pipe1)[0], buffer, strlen(buffer));
您正在对未初始化的缓冲区调用 strlen
。这允许使您的程序崩溃。相反,你很幸运,它所做的只是告诉 read
读取零字节,所以 read
没有做任何事情就返回了。
你真正想要的是
ssize_t nread = read(((int *)pipe1)[0], buffer, sizeof buffer - 1);
if (nread < 0) {
perror("read");
return 0;
}
buffer[nread] = '[=11=]';
read
想要被告知的是 space 你给它读了多少,而不是可能或可能还没有在 space 中。那是 sizeof buffer
,减一所以我们总是有 space 添加字符串终止符。
写时使用strlen
是正确的,因为你只想写实际的字符串,而不是任何可能超出字符串末尾的垃圾;但是 write
不会将字符串终止符写入管道,因此 read
不会 读取 一个,因此您必须手动添加它。当然,还要经常检查错误。
此外,请记住线程 运行 同时 。即使修复了这个错误,write
可能在 reader-thread 调用 read
时已经发生,如果没有,它可能很快就会发生。如果你想观察 reader-thread 实际上阻塞在 read
你需要在调用 write
.
之前延迟
我正在试验如何在 C 中的线程和主函数之间进行通信 以下代码中存在我不理解的行为:
#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
void* output(void* pipe1);
int main(int argc, const char *argv[])
{
pthread_t tid0;
int pipe1[2];
char buffer[200];
// Creating the pipe
pipe(pipe1);
// Creating the thread and passing the pipe as argument
pthread_create(&tid0, NULL, output, &pipe1);
// Input from user
scanf("%s", buffer);
// Writing to the pipe
write(pipe1[1], buffer, strlen(buffer));
return 0;
}
void* output(void* pipe1) {
char buffer[200];
// Reading the pipe and print the buffer
read(((int*)pipe1)[0], buffer, strlen(buffer));
printf("thread say: %s\n", buffer);
pthread_exit(NULL);
}
为什么读取函数不会阻塞管道的文件描述符?
也许我应该关闭管道的末端,但由于它们共享相同的内存space,当我调用读取或写入时返回错误"bad file descriptor"。
如果管道确实是一个糟糕的解决方案,也许你可以指导我使用其他方法(举个例子,它会很棒!:))
非常感谢!
编辑:解决方案
非常感谢您的回答,这里是具有预期行为的代码
#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
void* output(void* pipe1);
int main(int argc, const char *argv[])
{
pthread_t tid0;
int pipe1[2];
char buffer[200];
// Creating the pipe
pipe(pipe1);
// Creating the thread and passing the pipe as argument
pthread_create(&tid0, NULL, output, &pipe1);
// Input from user
scanf("%s", buffer);
// Writing to the pipe
if (write(pipe1[1], buffer, strlen(buffer)) < 0) {
perror("write");
exit(1);
}
// join so the main "wait" for the thread
pthread_join(tid0, NULL);
return 0;
}
void* output(void* pipe1) {
char buffer[200];
int nread;
// Reading the pipe and print the buffer
nread = read(((int*)pipe1)[0], buffer, sizeof buffer - 1);
if (nread < 0) {
fprintf(stderr, "ERROR\n");
perror("read");
exit(1);
}
buffer[nread] = '[=11=]';
fprintf(stderr, "thread say: %s\n", buffer);
pthread_exit(NULL);
}
char buffer[200];
read(((int*)pipe1)[0], buffer, strlen(buffer));
您正在对未初始化的缓冲区调用 strlen
。这允许使您的程序崩溃。相反,你很幸运,它所做的只是告诉 read
读取零字节,所以 read
没有做任何事情就返回了。
你真正想要的是
ssize_t nread = read(((int *)pipe1)[0], buffer, sizeof buffer - 1);
if (nread < 0) {
perror("read");
return 0;
}
buffer[nread] = '[=11=]';
read
想要被告知的是 space 你给它读了多少,而不是可能或可能还没有在 space 中。那是 sizeof buffer
,减一所以我们总是有 space 添加字符串终止符。
写时使用strlen
是正确的,因为你只想写实际的字符串,而不是任何可能超出字符串末尾的垃圾;但是 write
不会将字符串终止符写入管道,因此 read
不会 读取 一个,因此您必须手动添加它。当然,还要经常检查错误。
此外,请记住线程 运行 同时 。即使修复了这个错误,write
可能在 reader-thread 调用 read
时已经发生,如果没有,它可能很快就会发生。如果你想观察 reader-thread 实际上阻塞在 read
你需要在调用 write
.