接上层嵌入式Linux系统编程常见问题解答(一)
6:假设上一题中编译生成可执行文件名为tme。若在另一进程中调用system("./tme"),也会运行显示时间的程序。要求根据system函数的内部实现过程,用其它学过的函数实现与system("./tme")同样的功能。
答案:
#include <stdio.h>
#include <unistd.h>
extern char **environ;
int main()
{
pid_t pid = fork();
if(pid > 0)
{
waitpid(pid, NULL, 0);
}
else
{
char *buf[] = {"./tme", NULL};
execve("./tme", buf, environ);
}
return 0;
}
7:调用函数创建一个子进程,父进程从键盘读入一个整数,然后子进程把这个整数输出来。要求:信号是进程间通信的一种方式,本题要求利用信号知识实现,不能通过写入文件或管道等其它方式实现。
答案:
/*提示:任何整数都是由0-9这几个位组成的,可以把它的每个位都以信号的方式发给子进程,子进程接受到它的每个位后再计算出值。但有些信号比较特殊不能捕捉处理,故这里用信号10代表数字9,信号12代表数字0,信号11代表通信结束。其它的数字与其信号值相同。因为使用到了数学库函数pow,编译的时候最后带上-lm选项*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void fun(int n);
int main()
{
int a = fork();
if(a > 0)
{
int num;
printf("Input a number:\n");
scanf("%d", &num);
sleep(1);
/*从低到高以信号的形式向子进程发送该整数的每个位*/
int num1 = num;
do{
if(num1%10 == 9)
kill(a, 10);
else if(num1%10 == 0)
kill(a, 12);
else
kill(a, num1%10);
num1 = num1/10;
sleep(1);
}while(num1 != 0);
kill(a, 11);
waitpid(a, 0, 0);
}
else
{
/*对相关信号注册捕捉处理函数*/
signal(1, fun);
signal(2, fun);
signal(3, fun);
signal(4, fun);
signal(5, fun);
signal(6, fun);
signal(7, fun);
signal(8, fun);
signal(10, fun);
signal(11, fun);
signal(12, fun);
while(1)
sleep(1);
}
return 0;
}
/*子进程收到相关信号会调用此函数,此函数用来根据各个位计算出整数的值*/
void fun(int n)
{
static int m, i;
if(n == 10)
{
printf("第%d位是 9\n", i + 1);
m = m + 9 * pow(10, i);
i++;
}
else if(n == 12)
{
printf("第%d位是 0\n", i + 1);
//m = m + 0 * pow(10, i);
i++;
}
else if(n == 11)
{
printf("The number is %d\n", m);
sleep(1);
exit(0);
}
else
{
printf("第%d位是 %d\n", i + 1,n);
m = m + n * pow(10, i);
i++;
}
}
8:不用网络编程,用其它的IPC方式写一个模拟聊天过程的小程序。A进程终端下输入消息内容,按Enter后发送消息给B进程,B进程收到消息后在终端下显示消息内容。
B进程也能实现同样的功能。要显示出接收消息的时间。要能循环发送接收,如果输入QUIT就退出。
答案:
/*QQA.c*/
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#define BUFFER 255
#define SIZE sizeof(struct msgbuf)
void showime();
int msgid;
struct msgbuf{
long mtype;
char mtext[BUFFER + 1];
};
void* recv(void *p);
void* send(void *p);
int main()
{
msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
if(msgid == -1)
{
perror("msgget error!");
exit(-1);
}
pthread_t pthid_send, pthid_recv;
pthread_create(&pthid_send, NULL, send, NULL);
pthread_create(&pthid_recv, NULL, recv, NULL);
pthread_join(pthid_send, NULL);
pthread_join(pthid_recv, NULL);
msgctl(msgid, IPC_RMID, NULL);
return 0;
}
void showtime()
{
time_t tt = time(NULL);
struct tm *pTm;
pTm = localtime(&tt);
printf("%02d-%02d",(1 + pTm->tm_mon), (pTm->tm_mday));
printf(" %02d:%02d:%02d\n",(pTm->tm_hour), (pTm->tm_min), (pTm->tm_sec));
printf(" ");
}
void* send(void *p)
{
struct msgbuf msgsend;
while(1)
{
printf(" I say");
showtime();
memset(&msgsend, 0, SIZE);
msgsend.mtype = 1;
scanf("%s", msgsend.mtext);
if(strcmp(msgsend.mtext, "QUIT") == 0)
exit(0);
else
msgsnd(msgid, &msgsend, SIZE, 0);
}
}
void* recv(void * p)
{
struct msgbuf msgrecv;
while(1)
{
memset(&msgrecv, 0, SIZE);
msgrcv(msgid, &msgrecv, SIZE, 2,0);
if(strcmp(msgrecv.mtext, "QUIT") == 0)
exit(0);
else
{
printf(" Jim say ");
showtime();
printf("%s\n", msgrecv.mtext);
}
}
}
/*QQB.c*/
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#define BUFFER 255
#define SIZE sizeof(struct msgbuf)
void showime();
int msgid;
struct msgbuf{
long mtype;
char mtext[BUFFER + 1];
};
void* recv(void *p);
void* send(void *p);
int main()
{
msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
if(msgid == -1)
{
perror("msgget error!");
exit(-1);
}
pthread_t pthid_send, pthid_recv;
pthread_create(&pthid_send, NULL, send, NULL);
pthread_create(&pthid_recv, NULL, recv, NULL);
pthread_join(pthid_send, NULL);
pthread_join(pthid_recv, NULL);
msgctl(msgid, IPC_RMID, NULL);
return 0;
}
void showtime()
{
time_t tt = time(NULL);
struct tm *pTm;
pTm = localtime(&tt);
printf("%02d-%02d",(1 + pTm->tm_mon), (pTm->tm_mday));
printf(" %02d:%02d:%02d\n",(pTm->tm_hour), (pTm->tm_min), (pTm->tm_sec));
printf(" ");
}
void* send(void *p)
{
struct msgbuf msgsend;
while(1)
{
printf(" I say");
showtime();
memset(&msgsend, 0, SIZE);
msgsend.mtype = 2;
scanf("%s", msgsend.mtext);
if(strcmp(msgsend.mtext, "QUIT") == 0)
exit(0);
else
msgsnd(msgid, &msgsend, SIZE, 0);
}
}
void* recv(void * p)
{
struct msgbuf msgrecv;
while(1)
{
memset(&msgrecv, 0, SIZE);
msgrcv(msgid, &msgrecv, SIZE, 1,0);
if(strcmp(msgrecv.mtext, "QUIT") == 0)
exit(0);
else
{
printf(" Lucy say ");
showtime();
printf("%s\n", msgrecv.mtext);
}
}
}