fork函数、exec函数和pthread库函数的使用

抽时间整理一下操作系统布置过的大作业。第一次大作业是编译linux内核,这部分在之前的blog里写过了,这篇记录的是第二次大作业的内容。

首先,我们以大作业的要求来作导入。

要求.png

整个任务的要求大概就是,第一个进程A创建一个子进程B,再在进程B中创建两个线程,分别完成不同的工作。

在具体分析问题之前,我们需要了解学习一下几个函数。这里我就丢几个链接了,讲的十分详细,很有帮助。

fork函数&子进程与父进程&守护进程
linux c语言 fork() 和 exec 函数的简介和用法
linux创建线程之pthread_create

下面就开始代码的编写。

首先是第一个主模块,即进程A创建进程B部分。这里父进程A通过调用fork()创建子进程B,通过wait()等待子进程B结束,而B通过exec()函数调用另一个文件作为它的“替身”而自己被替身所替代,从而便于在另一个文件编写有关创建线程的部分。

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

int main()
{
    pid_t pid;
    pid=fork();

    if(pid<0){
        printf("Fork failed");
        exit(-1);
    }
    else if(pid==0){
        printf("Child process start,child pid is %d.\n",getpid());
        //exec..
        char *buf[]={"/home/wzp/charpter2/procedure2","procedure2",NULL};
        execve("/home/wzp/charpter2/procedure2",buf,NULL);
    }
    else{
        printf("Hello world,father pid is %d.\n",getpid());
        wait(NULL);
        exit(0);
    }
}

然后是子进程B变身后的新文件部分,即产生线程部分。

这里程序又分为三个模块,main作为主函数,即子进程B的替身,它又通过pthread_create()函数生成两个线程完成监视输入和计算的工作,故共三个线程。

主线程通过pthread_join()函数等待一个thread结束,但这里实际运行时并不会运行到这一步,因为在线程内部会通过exit()结束进程的运行。这里只是为了使pthread_join()和pthread_create()对应。

这一部分遇到了不少问题...

为了保证两个功能实现线程的信息交流,使用了几个全局变量,在注释中也有标注。当时进行编写的时候,考虑到互斥的问题,故使用了互斥锁进行保护,但测试时候对于互斥区的保护总是出现问题,导致对于功能实现总是有一个功能无法实现,改进一个功能又会导致另一个功能出现问题。最终“一气之下”把互斥锁删去,结果竟然能够正常运行了...我也是有些懵逼,遂放弃使用互斥锁,选择在恰当的地方使用条件变量conditions和sleep()进行二者互斥和部分提示信息的顺序排序。

还遇到的问题就是对于输入信息不确定为符号还是数字的问题,询问同学后才知道如何解决,即使用union联合,再通过scanf()的返回值来进行分类处理。这里就吃了当初c后半部分没学好的亏...很少用到union等知识导致编写程序根本想不到...以后多积累经验吧。

还有就是缓冲区问题。当输入一个未定义符号时,等待下一次重新输入,需要情况缓冲区,而windows的fflush(stdin)不能在linux环境下运行,故采用set(stdin,NULL)函数来清除缓冲区。这也是这次实验学到的。

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

//pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*初始化互斥锁*/
//pthread_cond_t  cond = PTHREAD_COND_INITIALIZER;//init cond

void *Input(void* arg);
void *Sum(void* arg);

union member{
    int a;
    char b;
}x;
int sum=0;    //全局变量sum,x
int m; //m is an variate to store x.a.
char n; //n is an variate to store x.b. 
_Bool flag,conditions; //flag distinguishes int(1) and char(0);conditions functions like "pthread_cond_signal(&cond)" from Input to Sum but also from Sum to Sum.

void *Input(void* arg)
{
    printf("Please input an integer or a character:\n");
    //printf("**pthread 1 starts.\n");
while(1)
 {  
    if(scanf("%d",&x.a))
    {
        m=x.a;
        flag=1;
                
        conditions=1;
        //printf("**pthread 1 signal conditions to 2.\n");
    }
    else 
    {
        scanf("%c",&x.b);
        n=x.b;
        flag=0;
    
        conditions=1;
        //printf("**pthread 1 signal conditions to 2.\n");  
    }

    //printf("**pthread 1 releases lock.\n");

    sleep(2);
 }
}

void *Sum(void* arg)
{
while(1)
 {
    //printf("**pthread 2 starts.\n");
    int i;
    
    sleep(1);

    while(!conditions)  sleep(1);

    sleep(2);

    //printf("**pthread 2 gets conditions.\n");

    //printf("**flag in pthread2 is %d\n",flag);
    if(flag)
    {
    
        for(i=0,sum=0;i<=m;i++)
        {
          sum=sum+i;
        }
        
        printf("the sum from 0 to %d is %d\n",m,sum);
            
        conditions=0;
        sleep(1);
        printf("Please input an integer or a character:\n");
    }
    else
    { 
    
    //printf("**judging the type of character.\n");
        switch(n)
        {
          case 'p': 
            {
                printf("Please input an integer or a character:\n");
                while((!flag)&&(n=='p'))    
                { 
                sleep(1);
                }
                                
                //conditions=1;
                break;
            };//stop Sum, use loop
          case 'e': 
            {
                printf("exit.\n");  
                exit(0);
                break;
            };//exit sum.exe
          default:  
            {
                printf("error.\n");
                printf("Please input an integer or a character:\n");
                setbuf(stdin, NULL);
                break;  
            };//child process continue.
        }
    
    //printf("**pthread 2 ends.\n");
    }
   
 }   
}



int main()
{
    printf("exec success.\n");

    pthread_t id1,id2;

    pthread_create(&id1,NULL,Input,(void*)NULL);
    pthread_create(&id2,NULL,Sum,(void*)NULL);

    pthread_join(id1,NULL);//wait thread end
    pthread_join(id2,NULL);

    //pthread_mutex_destroy(&mutex);
    //pthread_cond_destroy(&cond);
    exit(0);

    return 0;
}

最后就是编译运行了,这里注意因为使用了线程,故编译命令后面要加上-lpthread,否则会出错。

贴一张运行截图。

运行.png

大概就是这样了,总之就是一开始看到问题一脸懵逼,各种函数都不会用。后来查了些资料了解了用法,再把问题分成几个模块,一步一步做就做成功了。调试阶段耗精力较多,但最终成功后还是比较开心。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,198评论 6 514
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,334评论 3 398
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,643评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,495评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,502评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,156评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,743评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,659评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,200评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,282评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,424评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,107评论 5 349
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,789评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,264评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,390评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,798评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,435评论 2 359

推荐阅读更多精彩内容