我有三个线程 - 第一个读取句子直到“;”给出,第二个计算这些句子中的字符,第三个显示结果。
好吧,我只做了一句话,但通过管道发送数组似乎会产生一些问题(以及从一个线程读取多个字符串)。
为了阅读,我只能把字符串放一次,不能再放了。甚至整个功能上的互斥锁也不起作用。为什么会这样?
此外,在写入字符串后,我收到“写入:成功”消息。
这里有什么问题吗?
这是代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/stat.h>
#include <pthread.h>
#include <string.h>
int first[2];
int second[2];
void *input(void *ptr)
{
char str[100], ch = '0';
int length, i = 0;
while(1)
{
while(ch != ';')
{
printf("Enter the %d message: ", i + 1);
fflush(stdout);
length = read(STDIN_FILENO, str, sizeof(str));
if(write(first[1], str, sizeof(str)) != length)
{
perror("write");
exit(2);
}
if(length <= 0)
{
if(length == -1)
perror("read");
close(first[1]);
exit(2);
}
i++;
}
}
}
void *countChars(void *ptr)
{
char str[100];
int length, count = 0, i = 0;
while(1)
{
length = read(first[0], str, sizeof(str));
if(length <= 0)
{
if(length == -1)
perror("read");
close(first[0]);
close(second[1]);
exit(2);
}
if(write(STDOUT_FILENO, str, length) != length)
{
perror("write");
exit(2);
}
while(str[count] != '\n') count++;
write(second[1], &count, sizeof(count));
count = 0;
}
}
void *output(void *ptr)
{
int length, count = 0, i = 0;
while(1)
{
length = read(second[0], &count, sizeof(count));
if(length < sizeof(count))
{
close(second[0]);
exit(2);
}
printf("Number of characters: %d\n", count);
}
}
int main()
{
pthread_t t1, t2, t3;
if(pipe(first) == -1)
{
printf("First pipe error");
exit(1);
}
if(pipe(second) == -1)
{
printf("Second pipe error");
exit(1);
}
pthread_create(&t1, NULL, input, NULL);
pthread_create(&t2, NULL, countChars, NULL);
pthread_create(&t3, NULL, output, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_join(t3, NULL);
return 0;
}
编辑。
我认为问题是 - 如何从逻辑上解决这个问题?我是这样看的:
Thread1 -> (string) -> Thread2 -> (number of chars) -> Thread3 - save elements somewhere
...
Thread1 -> (ending string) -> Thread2 -> (number of chars removed later) -> Thread3 - display all elements
但是如果是这样的话——如何让线程像这样一个接一个地运行?如何在结束字符串上停止应用程序?将线程 3 中的那些整数值保存在哪里?
最佳答案
管道用于在进程之间传递数据,而不是线程。线程在同一进程中运行并可以访问同一内存,因此在这种情况下使用管道毫无意义。
具有三个进程的管道示例。父级向子级发送“hello world”,子级在字符串长度前添加字符串长度并将新字符串发送给孙级,孙级将其打印到标准输出。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
void parent(int fd_write) {
char *msg = "hello world";
ssize_t len = strlen(msg);
if (write(fd_write, msg, len) != len) {perror("parent write"); exit(1);}
}
void child(int fd_read, int fd_write) {
char msg_in[100], msg_out[150];
ssize_t len = read(fd_read, msg_in, sizeof msg_in);
if (len == -1) {perror("child read"); exit(1);}
msg_in[len] = '\0';
len = sprintf(msg_out, "%d: %s", (int)len, msg_in);
if (write(fd_write, msg_out, len) != len) {perror("child write"); exit(1);}
}
void grandchild(int fd_read) {
char msg[256];
ssize_t len = read(fd_read, msg, sizeof msg);
if (len == -1) {perror("grandchild read"); exit(1);}
msg[len] = '\0';
printf("Msg: %s\n", msg);
}
int main() {
enum {READ, WRITE};
pid_t pid;
int fd[2];
if (pipe(fd) == -1) {perror("first pipe"); exit(1);}
pid = fork();
if (pid == -1) {perror("first fork"); exit(1);}
if (pid == 0) {
int fd2[2];
if (pipe(fd2) == -1) {perror("second pipe"); exit(1);}
pid = fork();
if (pid == -1) {perror("second fork"); exit(1);}
if (pid == 0) {
close(fd2[WRITE]);
grandchild(fd2[READ]);
close(fd2[READ]);
exit(0);
}
close(fd[WRITE]); close(fd2[READ]);
child(fd[READ], fd2[WRITE]);
close(fd[READ]); close(fd2[WRITE]);
wait(NULL);
exit(0);
}
close(fd[READ]);
parent(fd[WRITE]);
close(fd[WRITE]);
wait(NULL);
return 0;
}
关于c - 如何使用管道在线程之间发送数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24342988/