【发布时间】:2018-09-04 19:57:05
【问题描述】:
我的程序必须这样做: 用户必须通过命令行为文件传递 N 个绝对路径名。然后第i个线程,0
当我运行它并为 N 个文件中的 1 个插入一个字符串并按 CTRL+C 时,在函数 onPress 中,函数 read 返回 0(我认为在这种情况下并不表示文件指针在文件结尾),它只打印字符串“Strings:”
代码:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <string.h>
#include <signal.h>
pthread_mutex_t mutex;
int fdGlobal;
void* writer (int* arg) {
int fd_in = *(arg);
char buffer[100];
pthread_mutex_lock(&mutex);
printf("Write the string that you want to insert in the file\n");
scanf("%s", &buffer);
write(fd_in, &buffer, strlen(buffer));
write(fdGlobal, &buffer, strlen(buffer));
printf("Finished\n");
pthread_mutex_unlock(&mutex);
}
void onPress(int sig) {
char buff[100];
printf("I'm going to print all strings passed in files...\n");
int rd = read(fdGlobal, &buff, sizeof(buff));
if (rd == -1) perror("Error in the read of global file\n");
printf("I read %d bytes\n", rd);
printf("Strings: %s\n", buff);
exit(0);
}
void main (int argc, char* argv[]) {
int fds[argc-1];
pthread_t tid[argc-1];
int i, mu;
if (argc<=1) {
printf("Insert a number >=1 of pathname/s\n");
}
for ( i = 1 ; i<argc; i++) {
if (argv[i][0] != '/') {
printf("Insert a pathname\n");
}
}
signal(SIGINT, onPress);
fdGlobal = open("globalFile.txt", O_CREAT|O_RDWR, 0666);
if (fdGlobal == -1) perror("Error in the open of global file\n");
mu = pthread_mutex_init(&mutex, NULL);
if (mu < 0) perror("Error in the creation of mutex\n");
for (i=0; i<argc-1; i++) {
fds[i] = open(argv[i+1], O_CREAT|O_WRONLY, 0666);
if (fds[i] < 0 ) perror("Error in the open of the file\n");
pthread_create ( &tid[i], NULL, (void*) writer, &(fds[i]) );
}
for (i=0; i<argc-1; i++) {
pthread_join(tid[i], NULL);
}
}
【问题讨论】:
-
当我运行它并为 N 个文件中的 1 个插入一个字符串并按 CTRL+C 在按
CTRL-C之前是否按“Enter”?如果没有,您的进程永远不会读取输入。此外,您只能从信号处理程序安全地调用异步信号安全函数。 POSIX 异步信号安全函数列表位于pubs.opengroup.org/onlinepubs/9699919799/functions/… 调用不在列表中的函数可以调用未定义的行为。此外,read()和write()返回ssize_t,而不是int。 -
潜在问题:未检查
scanf的返回码。使用scanf读取字符串而不指定目标缓冲区大小。使用read读取的打印缓冲区没有添加终止'\0'。在信号处理程序中使用非异步信号安全函数。也许更多。只要有这种UB情况,尝试解决代码的奇怪行为是没有意义的。 -
“没有任何同步”似乎不是一个恰当的描述,@n.m。线程函数的大部分主体都受到互斥体的保护。
-
@JohnBollinger 哎哟,我一定要瞎了。确实所有东西都被互斥了,但这意味着仍然没有并行性。
-
小记:避免使用
signal,改用sigaction(可移植性)。
标签: c multithreading posix eof