如果使用P进程在数组中存在值,我怎么能更快地确定?这是我到目前为止所尝试的。我把数组拆分成碎片,这样每个子进程都会检查一个部分(除法和工作)。找到该值后,子进程将写入管道。父进程将读取管道,如果有读取的内容,则会显示一条消息:找到该值。我想要了解的是:如何发信号通知其他子进程发现值并停止搜索。
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <sys/wait.h>
#define P 10
#define SIZE (sizeof(elementsList)/sizeof(elementsList[0]))
static pid_t pid[P];
static int elementsList[] = { }; //some values
void findValue(int elemList[], int start, int step, int size, int value,
int wPipe)
{
int i;
for (i = start; i < size; i += step)
{
if (value == elemList[i])
{
write(wPipe, &elemList[i], sizeof elemList[i]);
}
}
}
int main()
{
int fd[2];
int result;
int nbytes;
int child;
int valueToFind;
int wPid;
printf("Enter the value to be found: \n");
scanf("%d", &valueToFind);
if (pipe(fd) < 0)
{
perror("pipe");
}
for (child = 0; child < P; child++)
{
if ((pid[child] = fork()) < 0)
{
perror("fork");
exit(1);
}
else if (pid[child] == 0)
{
close(fd[0]);
printf("Child #%d\n", getpid());
findValue(elementsList, child, P, SIZE, valueToFind, fd[1]);
close(fd[1]);
exit(0);
}
}
close(fd[1]);
int status = 0;
nbytes = read(fd[0], &result, sizeof result);
printf("Parent reads %d bytes\n", nbytes);
if (nbytes > 0)
{
printf("The value %d was found\n", result);
}
else
{
printf("The value wasn't found.\n");
}
wPid = wait(&status);
if (WIFEXITED(status))
{
int returnCode = WEXITSTATUS(status);
if (returnCode == 0)
{
printf("Child %d exit status is 0\n", wPid);
}
for (child = 0; child < P; child++)
{
kill(pid[child], SIGTERM);
}
}
return 0;
}
P.S我必须使用fork()
来实现它答案 0 :(得分:0)
到目前为止,我是新手,到目前为止我只能使用烟斗。我的问题是,如果 可以等到第一个进程退出并在此之后 调用read或首先进行读取,只有在有东西的情况下 写入终止其他进程,因为找到了值。 使用kill可以吗?我用第二种方法编辑了代码。
kill
还可以。这听起来是不可避免的,但实际上有不同的信号,有些可以被捕获,有些则不能(SIGKILL
,SIGSTOP
)。
SIGTERM
安装信号处理程序以进行任何清理(分配可能只是在现代系统上删除 - >更快)并通过向其发送信号来终止相同的进程。CTRL+C
也会发送SIGTERM
。您可以替代或另外使用SIGUSR1
和SIGUSR2
用于特定用途。exit()
。有关详细信息,请参阅此讨论:Can exit() fail to terminate process? void
fatal_error_signal (int sig)
{
/* Since this handler is established for more than one kind of signal,
it might still get invoked recursively by delivery of some other kind
of signal. Use a static variable to keep track of that. */
if (fatal_error_in_progress)
raise (sig);
fatal_error_in_progress = 1;
/* Now do the clean up actions:
- reset terminal modes
- kill child processes
- remove lock files */
...
/* Now reraise the signal. We reactivate the signal's
default handling, which is to terminate the process.
We could just call exit or abort,
but reraising the signal sets the return status
from the process correctly. */
signal (sig, SIG_DFL);
raise (sig);
}
来源:http://ftp.gnu.org/old-gnu/Manuals/glibc-2.2.3/html_chapter/libc_24.html#SEC488