我的系统通话使用错误

时间:2018-08-13 16:05:17

标签: c linux operating-system system system-calls

我正在尝试通过分治法来实现线性搜索,并将每个子问题赋予我使用fork创建的新过程。

这是完整的代码:

#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<unistd.h>


int PID ; 

unsigned long long LinearSearchHelper(unsigned long long arr[] , unsigned long long low , unsigned long long high, unsigned long long key)
{
    if(low>high) exit(0) ; 
    if(low==high)
        exit(arr[low]==key ? low : 0 ) ; 

    unsigned long long mid = (low+high)/2 ;

    int leftProcess = fork() ; 
    if(leftProcess==0){
        exit(LinearSearchHelper(arr , low , mid , key)) ; 
    }

    int rightProcess = fork() ; 

    if(rightProcess==0)
    {
        exit(LinearSearchHelper(arr , mid+1 ,high , key)) ;
    }

    if(leftProcess<0 || rightProcess<0){
        printf("\nFAILED TO FORK PROCESS !" ) ; 
        exit(0) ; 
    }

    unsigned long long stat1 , stat2 ; 
    waitpid(leftProcess , &stat1 , 0  ) ; 
    waitpid(rightProcess , &stat2 , 0 ) ; 

    unsigned long long l = WEXITSTATUS(stat1) ; 
    unsigned long long r = WEXITSTATUS(stat2) ; 

    exit(l!=0?l : r) ;
}


unsigned long long LinearSearch(unsigned long long arr[] , unsigned long long low , unsigned long long high, unsigned long long key)
{
    int taskid = fork() ; 
    if(taskid<0){
        printf("\nFAILED TO FORK PROCESS !" ) ; 
    }
    int res ; 
    if(taskid==0){
        exit(LinearSearchHelper(arr , low , high , key)) ;
    }
    else{
        unsigned long long status ; 
        waitpid(taskid , &status , 0 ) ;
        return WEXITSTATUS(status) ; 
    } 
}



void fnGenRand(unsigned long long arr[] , unsigned long long n )
{
    unsigned long long i =0 ; 
    for(i = 0 ; i < n ; i++) {
        arr[i] = rand() %10000 ; 
    }
}



unsigned long long main(void)
{
    PID = getpid() ; 
    unsigned long long size = 400000 ; 
    unsigned long long  * arr = malloc(size * sizeof(unsigned long long))  ;  
    unsigned long long  i =0 , n = 200 ;
    struct timeval tv ; 
    double start , end ;
    srand(time(NULL)) ; 
    FILE * fp = fopen("mergeplot.dat" ,"w") ; 

    unsigned long long key ; 


    for(i=100 ; i<300; i+=30)
    {
        n =  i; 

        fnGenRand(arr , n  ) ; 

        key = rand()%10000 ; 

        gettimeofday(&tv , NULL) ; 
        start = tv.tv_sec + (tv.tv_usec/1000000.0) ; 
        unsigned long long res = LinearSearch(arr , 0 , n-1  , key ) ; 
        gettimeofday(&tv , NULL) ; 
        end = tv.tv_sec + (tv.tv_usec/1000000.0) ; 

        fprintf(fp , "%d\t%1lf\n" , i , end-start) ; 
    }

    fclose(fp) ; 
}

问题是我想将当前数组的大小和相应的搜索时间写入文件“ mergeplot.dat”中。

但是我面临的问题是mergeplot.dat文件越来越多的重复条目,我无法弄清楚出了什么问题以及为什么?

似乎多个进程正在一次写入我的文件,因此出现了重复的大小条目。我分叉并调用递归函数的方式有问题吗?

请提供关于我在做什么错的解释。我是系统调用的新手。

1 个答案:

答案 0 :(得分:2)

您对waitpid()的论点是错误的。 waitpid() is declared as

#include <sys/wait.h>

pid_t waitpid(pid_t pid, int *stat_loc, int options);

请注意,第二个选项是int *。您正在向waitpid()传递unsigned long long的地址:

unsigned long long status ; 
waitpid(taskid , &status , 0 ) ;

那行不通。

您的子进程可以返回的范围也可能会出现问题。一个进程只能提供0-255范围内的返回值。根据{{​​3}}:

  

WEXITSTATUS(wstatus)

     

返回孩子的退出状态。这最少   子级所指定的status参数的有效8位   调用exit(3)或_exit(2)或作为参数                 用于main()中的return语句。这个宏应该是                 仅在WIFEXITED返回true时使用。