我正在尝试输出由多个进程创建的有序行集。
我发现printf()
和fprintf()
不适合此类任务。现在我正在使用这组命令:
sprintf(buff,"%d: some string", (*counter)++); //build string (write can't do that)
write(file, buff, strlen(buff));
memset(buff, 0, strlen(buff)); //clear buffer before next writing
文件打开和启动过程如下所示:
int file;
int main(){
pid_t busPID, riderPID;
file = open("outputFile.txt", O_WRONLY | O_CREAT | O_APPEND | O_TRUNC, 0666);
if((busPID = fork()) == 0){
bus();
else{
if((riderPID = fork()) == 0){
for(int i = 0; i < 10; i++){
rider();
}
}else{
pid_t waitPID;
while ((waitPid = wait(&status)) > 0); //wait for all riders to finish
}
}
waitpid(busPID, NULL, 0);
return 0;
}
以下是打印输出的函数:
void bus() {
char buff[50];
//writing
do {
//writing
if(*onStop > 0) {
//writing
sem_post(semRider);
sem_wait(semBus);
//writing
*onStop = 0; //internal value, irrelevant for answer
}
//writing
usleep(rand()%busSleep);
//writing
sem_post(semRider);
sem_wait(semBus);
departuredAkt += temp; //internal value, irrelevant for answer
} while(departuredAkt < departuredTotal);
//writing
exit(EXIT_SUCCESS); //exit this process
}
void rider() {
char buff[50];
//writing
int pos = ++(*onStop);
//writing
sem_wait(semRider);
//writing
sem_post(semBus);
sem_wait(semRider);
//writing
sem_post(semBus);
exit(EXIT_SUCCESS);
}
只有1个进程使用bus()
函数,N个进程使用rider()
函数(由参数指定)。期望的输出是:
1: bus string
2: bus string
3: bus string
4: rider 1 string
5: rider 1 string
.
.
.
25: rider N string
26: bus string
我目前的输出如下:
1: bus string
2: bus string
3: bus string
4: rider 1 string
6: bus string //here is the problem
5: rider 1 string
问题是,如何以正确的顺序实现打印行?
答案 0 :(得分:1)
首先,旁注:永远不要使用sprintf
,这个功能完全不安全。使用snprintf
。例如:
snprintf (buff, sizeof (buff), "%d: some string", (*counter)++);
第二:您错过了我们理解您的问题所需的信息。我的意思是以下信息:
此详细信息对于理解您的问题至关重要。
下次你会写一些问题,请提供完整的例子。 I. e。我们可以编译和运行最小的工作示例。它应包括所有相关细节,即。即启动进程,打开文件等等。当然,你应该删除所有不必要的细节。
Okey,POSIX中有两种不同的概念:“文件描述符”和“文件说明”。为他们进行网络搜索。在UNIX shell中键入“man 2 open”并仔细阅读,本手册页介绍了区别。
有关如何启动流程以及如何打开文件的确切详细信息会导致(或不会导致)在进程之间共享文件描述,从而影响“写入”的行为。
我写了关于文件描述符和描述的大文本。我把它放在这里:https://zerobin.net/?eb2d99ee02f36b92#hQY7vTMCD9ekThAod+bmjlJgnlBxyDSXCYcgmjVSu2w=,因为它与这个问题没什么关系,但仍然对教育有用。
哦,该怎么办?
好吧,如果您因任何原因无法共享一个文件描述,那么只需使用O_APPEND打开文件即可。 :)每次写入文件时都不需要打开文件。只需在每个过程中用O_APPEND打开一次,一切都会好的。