UNIX IPC C程序只有父进程可以写入文件,子进程不工作
我需要使用Signal来用C编写UNIX进程间通信程序。我希望父进程和子进程写入同一个文件。 结果仅显示父级编写的文本。我可以使用BSD或System V。请帮助UNIX IPC C程序只有父进程可以写入文件,子进程不工作,unix,ipc,signals,Unix,Ipc,Signals,我需要使用Signal来用C编写UNIX进程间通信程序。我希望父进程和子进程写入同一个文件。 结果仅显示父级编写的文本。我可以使用BSD或System V。请帮助 #include <stdio.h> /* basic I/O routines. */ #include <unistd.h> /* define fork(), etc. */ #include <sys/types.h> /* define pid_t, etc.
#include <stdio.h> /* basic I/O routines. */
#include <unistd.h> /* define fork(), etc. */
#include <sys/types.h> /* define pid_t, etc. */
#include <sys/wait.h> /* define wait(), etc. */
#include <signal.h>
int myFlag = 0;
void myHandler(int);
int child_pid;
int main()
{
//oldmask = sigblock(sigmask(SIGUSR1));
sighold(SIGUSR1);
sighold(SIGINT);
/* critical region */
signal (SIGUSR1, myHandler);
sigrelse(SIGUSR1);
sigrelse(SIGINT);
child_pid = fork();
if (child_pid==0) {
for ( ; ; ) {
while(myFlag == 0)
sigpause(0);
sigblock (sigmask(SIGUSR1));
myFlag = 0;
FILE *fp=fopen("test","w");
fwrite("child",1,6,fp);
fclose(fp);
kill(getppid(),SIGUSR1);
}
}
if (child_pid>0){
FILE *fp;
fp=fopen("test","w");
fwrite("parent",1,6,fp);
fclose(fp);
for ( ; ; ) {
while(myFlag == 0)
sigpause(0);
sigblock (sigmask(SIGUSR1));
myFlag = 0;
fp=fopen("test","w");
fwrite("parent",1,6,fp);
fclose(fp);
}
kill(child_pid, SIGUSR1);
//kill ()-child_pid ;
}
exit(0);
}
void myHandler(int sigNo) {
myFlag = 1;
//signal (SIGUSR1, myHandler);
}
#包括/*基本I/O例程*/
#包括/*定义fork()等*/
#包括/*定义pid等*/
#包括/*定义等待()等*/
#包括
int myFlag=0;
void myHandler(int);
int-child_-pid;
int main()
{
//oldmask=sigblock(sigmask(SIGUSR1));
sighold(SIGUSR1);
sighold(SIGINT);
/*临界区*/
信号(SIGUSR1,myHandler);
sigrelse(SIGUSR1);
sigrelse(SIGINT);
child_pid=fork();
如果(子项pid==0){
对于(;;){
while(myFlag==0)
信号暂停(0);
sigblock(sigmask(SIGUSR1));
myFlag=0;
文件*fp=fopen(“测试”,“w”);
fwrite(“儿童”,1,6,fp);
fclose(fp);
kill(getppid(),SIGUSR1);
}
}
如果(子项pid>0){
文件*fp;
fp=fopen(“试验”,“w”);
fwrite(“父”,1,6,fp);
fclose(fp);
对于(;;){
while(myFlag==0)
信号暂停(0);
sigblock(sigmask(SIGUSR1));
myFlag=0;
fp=fopen(“试验”,“w”);
fwrite(“父”,1,6,fp);
fclose(fp);
}
kill(child_pid,SIGUSR1);
//kill()-child_-pid;
}
出口(0);
}
void myHandler(int sigNo){
myFlag=1;
//信号(SIGUSR1,myHandler);
}
您应该以追加模式而不是写入模式打开文件:
fp = fopen("test", "a");
这将把fp
的写入位置定位在文件的末尾而不是开头。当您使用“w”
打开时,您:
w或wb截断为零长度或创建用于写入的文件 然后,您可能需要考虑文件锁定,以防止两个进程同时写入文件 此外,您的子进程会写出nul终止符:
fwrite("child", 1, 6, fp);
但您的父进程没有:
fwrite("parent", 1, 6, fp);
这可能是你的意图,也可能不是,但看起来确实很奇怪。你的逻辑有缺陷。父进程在等待子进程向其发送信号之前不会向子进程发送信号。子进程等待父进程向其发送信号,然后再写入文件并向父进程发送信号 这意味着在父级中写入文件后,父级和子级都陷入繁忙的循环中,等待另一个执行某些操作 另外,虽然我不认为这是代码中的问题,因为调用
sigpause(0)
应使编译器相信全局变量可能已更改,需要重新加载,在其他情况下,您可能希望将myFlag
声明为volatile int myFlag代码>。这迫使编译器在每次引用它时从内存中读取或写入它的值
最后,当然,您的程序只需重复地在相同的字节上重新写入,因为您是在“w”
(写入)模式而不是“a”
(追加)模式下打开文件的
下面是一个程序,它使用POSIX标准调用和技术实现了您想要的功能,而不是您使用的旧的不推荐的过时调用:
#include <stdio.h> /* basic I/O routines. */
#include <unistd.h> /* define fork(), etc. */
#include <sys/types.h> /* define pid_t, etc. */
#include <sys/wait.h> /* define wait(), etc. */
#include <signal.h>
#include <stdlib.h>
volatile sig_atomic_t myFlag = 0;
void myHandler(int);
int child_pid;
int main()
{
signal (SIGUSR1, myHandler);
child_pid = fork();
if (child_pid==0) {
for ( ; ; ) {
while(myFlag == 0)
;
{
sigset_t oldmask;
sigset_t usr1;
sigemptyset(&oldmask);
sigemptyset(&usr1);
sigaddset(&usr1, SIGUSR1);
sigprocmask(SIG_BLOCK, &usr1, &oldmask);
myFlag = 0;
sigprocmask(SIG_SETMASK, &oldmask, NULL);
}
FILE *fp=fopen("test","a");
fwrite("child\n",1,6,fp);
fclose(fp);
kill(getppid(),SIGUSR1);
}
}
if (child_pid>0){
FILE *fp;
fp=fopen("test","a");
fwrite("parent\n",1,7,fp);
fclose(fp);
for ( ; ; ) {
kill(child_pid, SIGUSR1);
//kill ()-child_pid ;
while(myFlag == 0)
;
{
sigset_t oldmask;
sigset_t usr1;
sigemptyset(&oldmask);
sigemptyset(&usr1);
sigaddset(&usr1, SIGUSR1);
sigprocmask(SIG_BLOCK, &usr1, &oldmask);
myFlag = 0;
sigprocmask(SIG_SETMASK, &oldmask, NULL);
}
fp=fopen("test","a");
fwrite("parent\n",1,7,fp);
fclose(fp);
}
}
exit(0);
}
void myHandler(int sigNo) {
myFlag = 1;
//signal (SIGUSR1, myHandler);
}
#包括/*基本I/O例程*/
#包括/*定义fork()等*/
#包括/*定义pid等*/
#包括/*定义等待()等*/
#包括
#包括
易失性sig_atomic_t myFlag=0;
void myHandler(int);
int-child_-pid;
int main()
{
信号(SIGUSR1,myHandler);
child_pid=fork();
如果(子项pid==0){
对于(;;){
while(myFlag==0)
;
{
sigset\u t oldsmask;
sigset_t usr1;
SIGEPTYSET(&oldmask);
sigemptyset(&usr1);
sigaddset(&usr1,SIGUSR1);
sigprocmask(SIG_块、usr1和oldmask);
myFlag=0;
sigprocmask(SIG_设置掩码和旧掩码,NULL);
}
文件*fp=fopen(“测试”,“a”);
fwrite(“child\n”,1,6,fp);
fclose(fp);
kill(getppid(),SIGUSR1);
}
}
如果(子项pid>0){
文件*fp;
fp=fopen(“测试”、“a”);
fwrite(“父项”,1,7,fp);
fclose(fp);
对于(;;){
kill(child_pid,SIGUSR1);
//kill()-child_-pid;
while(myFlag==0)
;
{
sigset\u t oldsmask;
sigset_t usr1;
SIGEPTYSET(&oldmask);
sigemptyset(&usr1);
sigaddset(&usr1,SIGUSR1);
sigprocmask(SIG_块、usr1和oldmask);
myFlag=0;
sigprocmask(SIG_设置掩码和旧掩码,NULL);
}
fp=fopen(“测试”、“a”);
fwrite(“父项”,1,7,fp);
fclose(fp);
}
}
出口(0);
}
void myHandler(int sigNo){
myFlag=1;
//信号(SIGUSR1,myHandler);
}
尽量不要将代码缩进10-12个空格-这会使阅读变得非常困难,页面的右侧也会消失。最多8个空格;我使用4个空格,尽管有些人使用3个空格。您会发现一些书籍只使用了几个空格,但它们受到打印布局的限制……而且,sigrelse()
是POSIX中过时的函数。新代码(如您的)不应使用它。像你这样使用它们也有点毫无意义,IMNSHO。麻烦那些需要上床睡觉的孩子们……我要说的大部分要点都是你说的。将打开、写入和关闭文件的代码分解成一个函数是明智的。可以传递文件名;应该传递字符串;它可以使用'fprintf(fp,“%s\n”,str)
在字符串后面写一个换行符,这将提高可读性