gpt4 book ai didi

c - 向所有线程发送信号

转载 作者:太空宇宙 更新时间:2023-11-04 08:39:24 24 4
gpt4 key购买 nike

我正在尝试创建简单的信号处理 - 让我们说一些类似终止进程的事情。我的程序+主线程中有三个独立的线程。

问题是调用信号会导致当前线程终止,而其他线程仍在运行。

如何将信号发送到其余线程?如何在发送信号时区分这些信号?

顺便说一句,我必须在这里使用FIFO。

这是我到目前为止所得到的:

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/stat.h>
#include <pthread.h>
#include <string.h>
#include <signal.h>

int first[2];
int second[2];

#define FIFO_FILE "tmp/myfifo"

void *input(void *ptr)
{
char str[100], fifo[100];
int length;
FILE *fp;

while(1)
{
fp = fopen(FIFO_FILE, "r");
fgets(fifo, 100, fp);
if(fifo == "s1")
{
printf("SIGNAL 1!!!");
exit(1);
}

printf("Enter the message: ");
fflush(stdout);
length = read(STDIN_FILENO, str, sizeof(str));

if(str[0] == ';')
exit(2);

if(length <= 0)
{
if(length == -1)
perror("read");
close(first[1]);
exit(2);
}

if(write(first[1], str, length) != length)
{
perror("write");
exit(2);
}
}
}

void *countChars(void *ptr)
{
char str[100], fifo[100];
int length, count = 0;
FILE *fp;

while(1)
{
fp = fopen(FIFO_FILE, "r");
fgets(fifo, 100, fp);
if(fifo == "s1")
{
printf("SIGNAL 1!!!");
exit(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;
char fifo[100];
FILE *fp;

while(1)
{
fp = fopen(FIFO_FILE, "r");
fgets(fifo, 100, fp);
if(fifo == "s1")
{
printf("SIGNAL 1!!!");
exit(1);
}

length = read(second[0], &count, sizeof(count));
if(length < sizeof(count))
{
close(second[0]);
exit(2);
}

printf("Number of characters: %d\n", count);
}
}

void s1_handler(int signo)
{
FILE *fp;

if((fp = fopen(FIFO_FILE, "wb")) == NULL)
{
perror("fopen");
exit(2);
}

fputs("s1", fp);

fclose(fp);
}

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);

if(signal(SIGINT, s1_handler) == SIG_ERR)
{
printf("Cant catch SIGINT\n");
}

pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_join(t3, NULL);

return 0;
}

最佳答案

你的程序中有很多(概念上的)错误。

信号:标准信号(即非实时信号,如 SIGINT)不排队。您的流程只会收到一个信号,并且任何其他信号(相同类型)都将被丢弃,直到已经交付的信号以某种方式得到处理。信号(无论如何,大多数)作为一个整体传递给流程。如果你的程序没有采取其他行动,信号将被传递到进程内的任意线程。您可以使用pthread_kill 将您捕捉到的信号重新发送到您的其他线程,但这需要您通过使用例如全局TID 表。目前还不清楚您真正想用您的程序完成什么,但这几乎可以肯定不是您想要做的。

FIFO:您似乎知道使用 FIFO 在线程之间进行通信是一个可疑的设计,但如果您被告知要使用它们,那么您必须正确使用它们。

(1) 当 FIFO 打开时(未指定非阻塞模式)open 将阻塞,直到 FIFO 的每一端都有读取器和写入器。这意味着您的所有 3 个线程都将阻塞各自的 FIFO 打开调用,直到您的信号处理程序(请参阅下面的问题)运行并打开 FIFO 进行写入。

(2) 即使您通过了打开,也只有一个线程会读取和使用信号处理程序写入的字符串。其他线程将阻塞试图读取一个空的 FIFO,并且永远不会处理任何东西。目前您只是在读取 FIFO 的线程中调用 exit,这将结束程序,但这是您真正想要的吗?

(3) 不需要在每个线程都打开FIFO。您可以在创建线程之前执行此操作,然后将 FIFO 文件描述符传递给每个线程或将其设为全局。

(4) 您每次通过 while(1) 循环打开(而不是关闭)每个线程中的 FIFO。这样你会很快用完文件描述符。

信号处理程序:您不应在信号处理程序中使用非异步安全调用。您至少有 3 个 - fopen、fputs、fclose。理想情况下,你想做一些非常简单的事情,比如在信号处理程序中设置一个全局开关,然后退出。因此,如果这不仅仅是一项脑死亡的类作业,您应该完全重新考虑这一点。

我建议详细说明您的计划目标是什么,您可以获得一些关于如何实现目标的建议。

关于c - 向所有线程发送信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24487099/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com