[英]Synchronizing processes using USR signals
我正在編寫一個程序,其中:
我怎樣才能做到這一點? 到目前為止,我有:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
int main(int argc, char **argv)
{
int pid, c;
FILE *fpr, *fpw;
char str[512];
if((pid = fork()) == 0)
{
fpr = fopen("bufor", "r");
if(fpr == NULL)
exit(EXIT_FAILURE);
while(fscanf(fpr, "%[^\n]\n", str) != EOF)
{
printf("%s", str);
}
fclose(fpr);
exit(0);
}
fpr = fopen("/etc/profile", "r");
if(fpr == NULL)
exit(EXIT_FAILURE);
if(fpr)
{
while(fscanf(fpr, "%[^\n]\n", str) != EOF)
{
fpw = fopen("bufor", "w+");
if(sizeof(str) > 0)
{
fputs(str, fpw);
}
fclose(fpw);
}
fclose(fpr);
}
return 0;
}
它從文件讀取,寫入另一個文件等,但是沒有同步-輸出僅是最后一行。
我怎樣才能做到這一點?
此代碼似乎有效。 確保自己理解所有內容,然后再將其作為自己的內容進行傳遞。 我調用了文件sigsync.c
,因此調用了程序sigsync
,因此選擇了環境變量的名稱。
匯編:
gcc -g -O3 -std=gnu11 -Wall -Wextra -Wmissing-prototypes \
-Wstrict-prototypes -Werror sigsync.c -o sigsync
碼:
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static int verbose = 0;
static volatile sig_atomic_t sig_num = 0;
static void sigusr1(int signum)
{
sig_num = signum;
}
static void be_childish(const char *file, pid_t parent)
{
char str[512];
FILE *fpr = fopen(file, "r");
if (fpr == NULL)
{
fprintf(stderr, "Failed to open file %s for reading\n", file);
exit(EXIT_FAILURE);
}
while (1)
{
rewind(fpr);
pause();
if (verbose)
printf("Child: got %d\n", sig_num);
while (fscanf(fpr, "%511[^\n]\n", str) == 1)
printf("%s\n", str);
kill(parent, SIGUSR1);
sig_num = 0;
}
/*NOTREACHED*/
fclose(fpr);
}
static void be_parental(const char *file, pid_t child)
{
char str[512];
const char profile[] = "/etc/profile";
FILE *fpr = fopen(profile, "r");
if (fpr == NULL)
{
fprintf(stderr, "Failed to open file %s for reading\n", profile);
exit(EXIT_FAILURE);
}
while (fscanf(fpr, "%511[^\n]\n", str) != EOF)
{
if (strlen(str) > 0)
{
FILE *fpw = fopen(file, "w");
if (fpw == 0)
{
fprintf(stderr, "Failed to open file %s for reading\n", profile);
kill(child, SIGTERM);
exit(EXIT_FAILURE);
}
fprintf(fpw, "%s\n", str);
fclose(fpw);
kill(child, SIGUSR1);
pause();
if (verbose)
printf("Parent: got %d\n", sig_num);
sig_num = 0;
}
}
fclose(fpr);
kill(child, SIGTERM);
}
int main(void)
{
int child;
int parent = getpid();
const char filename[] = "bufor";
/* Make sure file exists and is empty */
FILE *fp = fopen(filename, "w");
if (fp == 0)
{
fprintf(stderr, "Failed to open file %s for writing\n", filename);
exit(EXIT_FAILURE);
}
fclose(fp);
if (getenv("SIGSYNC_VERBOSE") != 0)
verbose = 1;
struct sigaction sa;
sa.sa_handler = sigusr1;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGUSR1, &sa, 0) != 0)
{
fprintf(stderr, "Failed to set signal handler\n");
exit(EXIT_FAILURE);
}
if ((child = fork()) < 0)
{
fprintf(stderr, "Failed to fork\n");
exit(EXIT_FAILURE);
}
else if (child == 0)
be_childish(filename, parent);
else
be_parental(filename, child);
return 0;
}
樣本輸出:
請注意,前導空格已完全刪除。 父級讀取/etc/profile
中的代碼可以做到這一點,其原因很微妙。 "%511[^\\n]\\n"
格式不會跳過開頭的空格,但是末尾的\\n
不會被視為“僅匹配換行符”,而是被視為“匹配一系列空格”。 這意味着它將跳過換行符和下一行的空白行。 要保留空間,請使用fgets()
或getline()
而不是fscanf()
。 在具有GCC 5.1.0的Ubuntu 14.04衍生產品上進行了測試。
# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).
umask 027
if [ "$PS1" ]; then
if [ "$BASH" ]; then
PS1='\u@\h:\w\$ '
if [ -f /etc/bash.bashrc ]; then
. /etc/bash.bashrc
fi
else
if [ "`id -u`" -eq 0 ]; then
PS1='# '
else
PS1='$ '
fi
fi
fi
if [ -d /etc/profile.d ]; then
for i in /etc/profile.d/*.sh; do
if [ -r $i ]; then
. $i
fi
done
unset i
fi
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.