【问题标题】:Error in my system calls usage我的系统调用使用错误
【发布时间】:2019-01-20 10:15:49
【问题描述】:

我正在尝试通过分而治之来实现线性搜索,并将每个子问题赋予我使用 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 文件有很多重复的条目,我不知道出了什么问题,为什么?

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

请解释我做错了什么。我是系统调用的新手。

【问题讨论】:

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


    【解决方案1】:

    您对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 范围内的返回值。每the wait() man page:

    WEXITSTATUS(wstatus)

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

    【讨论】:

    • 我把 unsigned long long 改成 "int" 但还是一样的问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-02
    相关资源
    最近更新 更多