我有这个任务,我必须创建两个进程,每个进程必须生成50个奇数或偶数的整数。
编写一个简单的序列号系统,通过该系统,两个进程P1和P2每个都可以获得50个唯一的整数,这样一个接收所有奇数,另一个接收所有偶数。使用fork()调用来创建P1和P2。给定包含单个数字的文件F,每个进程必须执行以下步骤:
一个。打开F.
湾从文件中读取序列号N C。关闭F.
d。输出N和过程'PID(在屏幕或测试文件上) 即增加N乘以1 F。打开F.
G。将N写入F.
H。冲洗F.
一世。关闭F
作为suggested by SO user我在每个进程中创建了一个循环并运行上述步骤。但我不确定这种方法是否正确。我已经向我的助教求助了,他建议做同样的事情(使用睡眠呼叫并等待有效的整数)。但问题是我可以在不使用睡眠呼叫的情况下获得相同的结果。所以我不确定我是否正确地将逻辑应用于代码。有人可以帮忙吗?
这是我的实施:
void getUniqueNumbers() {
struct process p1;
struct process p2;
int numberFromFile;
pid_t pid = fork();
// Process 1
if (pid == 0) {
int p1Counter = 0;
p1.processId = getpid();
while(p1Counter < numLimit) {
numberFromFile = getNumberFromFile();
if (numberFromFile % 2 == 0) { // even
p1.numbers[p1Counter] = numberFromFile;
printf("N: %d, PID: %d\n", numberFromFile, p1.processId);
numberFromFile++;
writeNumberToFile(numberFromFile);
p1Counter++;
}
else {
sleep(1);
}
}
}
// Process 2
else if (pid > 0 ) {
int p2Counter = 0;
p2.processId = getpid();
while(p2Counter < numLimit) {
numberFromFile = getNumberFromFile();
if (numberFromFile % 2 != 0) { // odd
p2.numbers[p2Counter] = numberFromFile;
printf("N: %d, PID: %d\n", numberFromFile, p2.processId);
numberFromFile++;
writeNumberToFile(numberFromFile);
p2Counter++;
}
else {
sleep(1);
}
}
}
else {
printf("Error: Could not create process\n");
}
}
读/写功能:
// Returns the number included in user provided file
int getNumberFromFile() {
FILE *fp = fopen(fileName, "rb");
int num = 0;
if (fp != 0) {
char line[10];
if (fgets(line, sizeof(line), fp) != 0)
num = atoi(line);
fclose(fp);
}
return num;
}
// Writes a given number to the user provided file
void writeNumberToFile(int num) {
FILE *fp = fopen(fileName, "w");
if (fp != 0) {
fprintf(fp, "%d", num);
fclose(fp);
}
}
答案 0 :(得分:0)
代码看起来不错。它可以简化很多。
void getUniqueNumbers()
{
struct process p; // We need only 1 structure
size_t counter = 0; // sample counter
int oddEven; // flag if we are parent
pid_t pid = fork(); // Fork here
if (-1 == pid)
{
abort(); // simply die on error
}
oddEven = 0 == pid ? 0 : 1;
p.processId = getpid(); // We are either child or parent.
while (counter < numLimit)
{
int numberFromFile = getNumberFromFile();
if ((numberFromFile & 1) == oddEven)
{
p.numbers[counter++] = numberFromFile;
printf("N: %d, PID: %ld\n", numberFromFile, (long)p.processId);
numberFromFile++;
writeNumberToFile(numberFromFile);
}
sleep(1); // sleep in both cases
// Extra check for parent: if child has died, we are in infinite
// loop, so check it here
if (0 != pid && counter < numLimit)
{
int status = 0;
if (waitpid(pid, &status, WNOHANG) > 0)
{
printf("Child exited with 0x%08X status\n", status);
break;
}
}
}
// wait till child process terminates
if (0 != pid)
{
int status = 0;
waitpid(pid, &status, 0);
printf("Child exited with 0x%08X status\n", status);
}
}
此外,文件读/写应使用文件锁操作或原子文件更改。重要的是要防止潜在的错误,例如一个线程正在写入编号40006,而另一个线程则设法读取400.尽管不应该在现实生活中发生。
需要文件锁来防止对相同内容的并发访问。它可以是独占锁,也可以是共享读独占写。
原子修改是一种能够以原子方式替换文件内容的功能,无论编写数据所花费的操作数量多少。它是保持数据一致的替代方案。