Athony

os 实验复习简记
POSIX信号量的引用头文件是"",而SYSTEM V信号量的引用头文件是"<...
扫描右侧二维码阅读全文
22
2019/06

os 实验复习简记

POSIX信号量的引用头文件是"",而SYSTEM V信号量的引用头文件是"<sys/sem.h>"。

线程/进程

用到的程序头

#include <sys/types.h> 

#include <sys/ipc.h> 

#include <sys/shm.h> 

#include <sys/types.h>

#include <sys/wait.h>

#include <unistd.h>

#include <stdlib.h>

1.main()

  {

    char c;

    int shmid;

    key_t key;

    char *shm, *s;

    key = 5679;

   if ((shmid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0) {

        perror("shmget");

        exit(1);

    }

2.shmid = shmget (key, size, shmflg)

key_t key; /* key to be passed to shmget() */ 

int shmflg; /* shmflg to be passed to shmget() */ 

int shmid; /* return value from shmget() */ 

int size; /* size to be passed to shmget() */ 

管道:

函数原型:

#include <unistd.h>

int pipe(int fdes[2]);

 pipe函数成功后,内核打开两个文件描述字fdes[0],fdes[1]。

 fdes[0]输入端,fdes[1]为输出端。

 总流程:

int pipe(fildes); 

int fildes[2]

//建立进程间的通道,返回两个描述:

fildes[0] 用于读管道。

fildes[1] 用于写管道。

#include <unistd.h>  

      //执行程序使用

    int execl(const char *path, const char *arg, ...);  

    int execlp(const char *file, const char *arg, ...);  

    int execle(const char *path, const char *arg, ..., char *const envp[]);  

    int execv(const char *path, char *const argv[]);  

    int execvp(const char *file, char *const argv[]);  

    int execve(const char *path, char *const argv[], char *const envp[]); 

exec函数会取代执行它的进程, 即:

 一旦exec函数执行成功, 它就不会返回了, 进程结束;

但是如果exec函数执行失败, 它会返回失败的信息,  而且进程继续执行后面的代码。

管道只允许具有血缘关系的进程间通信,如父子进程间的通信。

管道只允许单向通信。

管道内部保证同步机制,从而保证访问数据的一致性。

面向字节流

管道随进程,进程在管道在,进程消失管道对应的端口也关闭,两个进程都消失管道也消失。

- 每个在task_struct结构中登记的进程都有相应的进程状态和进程标志

系统创建的第1个真正进程是init进程/systemd进程,pid=1。

系统中所有的进程都是由进程使用系统调用fork()创建的。

子进程被创建后继承了父进程的资源。子进程共享父进程的虚存空间(只读方式)。

写时拷贝 (copy on write):子进程在创建后共享父进程的虚存内存空间,只是在两个进程中某一个进程需要向虚拟内存写入数据时才拷贝相应部分的虚拟内存。

子进程在创建后执行的是父进程的程序代码。子进程通过调用exec系列函数执行真正的任务。

pthread_mutex_lock

pthread_mutex_unlock

软中断信号(SIGCHLD)

/arch:目录包括了所有和体系结构相关的核心代码。

它下面的每一个子目录都代表一种Linux支持的体系结构,例如i386就是IntelCPU及与之相兼容体系结构的子目录。PC机一般都基于此目录。

/drivers:目录中是系统中所有的设备驱动程序。

/ipc:目录包含了核心进程间的通信代码。

/kernel:内核管理的核心代码,此目录下的文件实现了大多数linux系统的内核函数,其中最重要的文件当属sched.c;同时与处理器结构相关代码都放在/arch/*/kernel目录下。

代码:

##fork

1.

#include<stdio.h>

main()

{

    int pid;

    pid = fork();

    //printf("pid= %d\n",pid);

    printf("pid= %d\n",getpid());

    sleep(1);   

}

结果会产生两个输出,pid一个是自身的,一个是子进程的

2.

#include <sys/types.h>

#include <unistd.h>

#include <stdio.h>

int main()

{

    pid_t pid;

    char *message;

    int n;

    printf("fork program starting\n");

    pid = fork();

    switch(pid) {

        case -1:

            perror("fork failed");

            return 0;

        case 0:

            message = "This is the child";

            n = 5;

            break;

        default:

            message = "This is the parent";

            n = 3;

            break;

    }

    for(; n > 0; n--) {

        puts(message);

        //sleep(1);

    }

    return 0;

}

两个进程分开进行,一个打印3次,一个打印5次

返回等于0 子进程

否则为 父进程

3.

#include <unistd.h>

#include <stdio.h>

#include <sys/types.h>

main( )

{

    int p1,p2;

    while ((p1=fork())==-1);             /*父进程创建第一个进程,直到成功*/

    if(p1==0)                         /*0返回给子进程 1*/

        {

            putchar('b');/*P1的处理过程*/ 

            }

    else   

    {                             /*正数返回给父进程(子进程号)*/

        while ((p2=fork())==-1);         /*父进程创建第二个进程,直到成功*/

        if(p2==0)                      /*0返回给子进程2*/

            {

            putchar('c');/*P2的处理过程*/

              }            

        else

            {

            putchar('a');/*P2创建完成后,父进程的处理过程*/

            }            

    }

}

父进程 子1进程 子2进程之间的打印

当程序并发执行的时候,因为系统处于一种高速运行的状态,所以程序每次执行的结果并不一样,由系统来决定相对的速度与顺序。

4.

#include <stdio.h>

#include <sys/types.h>

#include <sys/wait.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <unistd.h>

#include <errno.h>

#include <stdlib.h>

#include <string.h>

int main()

{

    char buf[100];

    pid_t cld_pid;

    int fd;

    if((fd=open("temp",O_CREAT|O_TRUNC|O_RDWR,S_IRWXU))==-1)

    {

        printf("open error%d",errno);

        exit(1);

    }

    strcpy(buf,"This is parent process write\n");

    if((cld_pid=fork())==0)

    {                                         /*这里是子进程执行的代码*/

        strcpy(buf,"This is child process write\n");

        printf("This is child process\n");

        sleep(1);

        printf("My PID (child) is%d\n",getpid());        /*打印出本进程的ID*/

        sleep(2); 

        printf("My parent PID is %d\n",getppid());       /*打印出父进程的ID*/

        sleep(3);

        write(fd,buf,strlen(buf));

        close(fd);

        exit(0);

    }

    else

    {                                         /*这里是父进程执行的代码*/

        //wait(0);                            /*如果此处没有这一句会如何?*/

        printf("This is parent process\n");

        sleep(1);

        printf("My PID (parent) is %d\n",getpid());       /*打印出本进程的ID*/

        sleep(1);

        printf("My child PID is %d\n",cld_pid);          /*打印出子进程的ID*/

        sleep(1);

        write(fd,buf,strlen(buf));

        close(fd);

    }

    return 0;

}

//两种结果

一种是父进程已经消亡,所以显示id为1,一种是还未消亡,所以显示id为具体的进程id

来回切换是因为 sleep的时间

如果使用父进程中的 wait(0) 第261行 则会使得父进程被阻塞,两者成为原子操作

#include <unistd.h>

#include <stdio.h>

#include <sys/types.h>

main()   

   {   

       pid_t    a_pid,b_pid;   

       if((a_pid=fork())<0)   

          printf("error!");   

       else  if(a_pid==0)   

             printf("b\n");   

       else   

             printf("a\n");   

       if((b_pid=fork())<0)   

          printf("error!");   

       else if(b_pid==0)   

             printf("c\n");   

       else   

             printf("a\n");   

       }   

#include <unistd.h>

#include <stdio.h>

#include <sys/types.h>

main()   

   {   

       pid_t    a_pid,b_pid;   

       if((a_pid=fork())<0)   

          printf("error!");   

       else   

         if(a_pid==0)   

             printf("b");   

         else   

             printf("a");   

       if((b_pid=fork())<0)   

          printf("error!");   

       else   

          if(b_pid==0)   

             printf("c");   

          else   

             printf("a");   

       }   

//

由于缓冲的存在,去掉/n之后,会使得缓冲区内的内容再次被打印出来。 (打印有8个字母)

不去掉/n 有6个

父亲 a 儿子1 b

父亲 a 儿子2 c  儿子1 c  孙子a

##pthread

//"hello world"单线程程序

# include <stdio.h>

const NUM = 5;

int main()

{

    void p_msg(char *);

    p_msg("hello");

    p_msg("world\n");

}

void p_msg(char *m)

{

    int i;

    for(i = 0 ; i < NUM ; i ++)

    {

        printf("%s",m);

        fflush(stdout);//清理缓存

        sleep(1);

    }

}

//调用函数p_msg  hello和word输出,通过清除缓存区,分别输出五次

#include <stdio.h>

#include <pthread.h>

main()

{

    pthread_t t1 , t2;

    void *p_msg(void *);

    pthread_create(&t1,NULL,p_msg,(void * )"hello ");

    pthread_create(&t2,NULL,p_msg,(void * )"world\n");

    pthread_join(t1, NULL);

    pthread_join(t2, NULL);

}

void *p_msg(void *m)

{

    int i;

    for(i = 0 ; i < 5 ; i ++)

    {

        printf("%s",m);

        fflush(stdout);

        sleep(1);

    }

    return NULL;

}

//输出5次hello world

//pthread_join换成pthread_exit,观察运行结果的变化。

用来等待一个线程结束,并且收回被等待线程的资源,主要是为了阻塞线程。

将其删除后的多次运行结果:

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

void thread(void)

{

    int i;

    for(i=0;i<3;i++)

    {

        printf("This is a pthread.\n");

        sleep(1);

    }

}

int main(void)

{

    pthread_t id;

    int i,ret;

    ret=pthread_create(&id,NULL,(void *) thread,NULL);

    if(ret!=0)

    {

        printf ("Create pthread error!\n");

        exit (1);

    }

    for(i=0;i<3;i++)

    {

        printf("This is the main process.\n");

        sleep(1);

    }

    pthread_join(id,NULL);

    return (0);

}

//循环交替输出

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

void *PrintThread(void * );

#define Num_Threads 3

int main()

{

    int i,ret;

    pthread_t a_thread;

    int ThdNum[Num_Threads];

    for (i = 0; i < Num_Threads; i++)

        ThdNum[i] = i;

    for(i = 0; i < Num_Threads;i++)

    {

        ret = pthread_create(&a_thread,NULL,PrintThread,(void *)&ThdNum[i]);

        if (ret == 0)

            printf("Thread launched succeddfully\n");

    }

    i = getchar();

    return (0);

}

//程序执行函数开始

void *PrintThread(void * num)

{

    int i;

    for(i = 0;i < 3; i++)

        {

        printf("thread number is %d\n",*((int *)num));

        sleep(1);

        }

    return NULL;

}

//2,1,0 各自输出三遍

没有固定顺序

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

void *PrintThread(void * );

pthread_mutex_t TestMutex=PTHREAD_MUTEX_INITIALIZER;

#define Num_Threads 3

int main()

{

    int i,ret;

    pthread_t a_thread;

    int ThdNum[Num_Threads];

    for (i = 0; i < Num_Threads; i++)

        ThdNum[i] = i;

    for(i = 0; i < Num_Threads;i++)

    {

        ret = pthread_create(&a_thread,NULL,PrintThread,(void *)&ThdNum[i]);

        if (ret == 0)

            printf("Thread launched succeddfully\n");

    }

    i = getchar();

    return (0);

}

void *PrintThread(void * num)

{

    int i;

    pthread_mutex_lock(&TestMutex);

    for(i = 0;i < 3; i++)

        {

        printf("thread number is %d\n",*((int *)num));

        sleep(i);

        }

    pthread_mutex_unlock(&TestMutex);

    return NULL;

}

//在上面的基础上加上了互斥锁

pthread_mutex_lock

pthread_mutex_unlock

#include <stdio.h>

-- #include <unistd.h>

#include <stdlib.h>

#include <string.h>

#include <pthread.h>

void *thread_function(void *arg); 

char message[] = "Hello World";

int main() {

        int res;

        pthread_t a_thread;

        void *thread_result;

        res = pthread_create(&a_thread, NULL, thread_function, (void *)message);

        if (res != 0) {

            perror("Thread creation failed");

            exit(EXIT_FAILURE);

        }

        printf("Waiting for thread to finish...\n");

        res = pthread_join(a_thread, &thread_result);

        if (res != 0) {

            perror("Thread join failed");

            exit(EXIT_FAILURE);

        }

        printf("Thread joined, it returned %s\n", (char *)thread_result);

        printf("Message is now %s\n", message);

        exit(EXIT_SUCCESS);

}

void *thread_function(void *arg) {

        printf("thread_function is running. Argument was %s\n", (char *)arg);

        sleep(3);

        strcpy(message, "Bye!");

        pthread_exit("Thank you for the CPU time");

}

//就是线程之间的相互调度

#include <stdlib.h>

#include <stdio.h>

#include <pthread.h>

#include <errno.h>

#include <sys/types.h>

#include <sys/syscall.h>

/*全局变量*/

int gnum = 0;

/*互斥量 */

pthread_mutex_t mutex;

/*声明线程运行服务程序*/

static void pthread_add2 (void);

static void pthread_add3 (void);

pid_t gettid() {

    return syscall(SYS_gettid);

}

int main (void)

{

 /*线程的标识符*/

  pthread_t pt_1 = 0;

  pthread_t pt_2 = 0;

  int ret = 0;

  printf ("main programme start,pid = %d,num = %d!\n",getpid(),gnum);

  /*互斥初始化*/

  pthread_mutex_init (&mutex, NULL);

  /*分别创建线程1、2*/

  ret = pthread_create( &pt_1, NULL,(void *)pthread_add2, NULL);  

  ret = pthread_create( &pt_2, NULL,(void *)pthread_add3, NULL); 

  /*等待线程1、2的结束*/

  pthread_join (pt_1, NULL);

  pthread_join (pt_2, NULL);

  printf ("main programme exit!\n");

  return 0;

}

/*线程1的服务程序*/

static void pthread_add2 (void)

{

  int i = 0;

  printf ("This is pthread_1!pid = %d,tid = %d,tid = %lu\n",getpid(),gettid(),pthread_self());

  for( i=0; i<3; i++ ){

    //pthread_mutex_lock(&mutex); /*获取互斥锁*/

    gnum++; sleep (1); gnum++;/*临界资源*/

    printf ("Thread_1 add 2 to num:%d\n",gnum);

    //pthread_mutex_unlock(&mutex); /*释放互斥锁*/

    }

  pthread_exit ( NULL );

}

/*线程2的服务程序*/

static void pthread_add3 (void)

{

  int i = 0;

  printf ("This is pthread_2!pid = %d,tid = %d,tid = %lu\n",getpid(),gettid(),pthread_self());

  for( i=0; i<4; i++ )  {

    //pthread_mutex_lock(&mutex); /*获取互斥锁*/

    gnum++; sleep (1);gnum++; sleep (1);gnum++; /*临界资源*/

    printf ("Thread_2 add 3 to num:%d\n",gnum);

    //pthread_mutex_unlock(&mutex); /*释放互斥锁*/

     }

  pthread_exit ( NULL );

} 

//因为运行过程中的不确定性和并发性,导致在打印为加2的时候交叉运行到另一个进程使得加的值为3而不为2,下面的加2变为加3是同一个原理所产生

关键是sleep的运行

#sem pthread

int sem_wait(sem_t *sem);等待信号量,如果信号量的值大于0,将信号量的值减1,立即返回。如果信号量的值为0,则线程阻塞。相当于P操作。成功返回0,失败返回-1。

int sem_post(sem_t *sem); 释放信号量,让信号量的值加1。相当于V操作。

#include <pthread.h>

#include <semaphore.h>

#include <sys/types.h>

#include <stdio.h>

#include <unistd.h>

int number; // 被保护的全局变量

sem_t sem_id1, sem_id2;

void* thread_white_fun(void *arg)

{

    int i;

    for(i = 0;i < 3;i++)

    {

        sem_wait(&sem_id1);

        printf("thread_white have the semaphore\n");

        number++;

        printf("number = %d\n",number);

        sem_post(&sem_id2);

        sleep(1);

    }

}

void* thread_black_fun(void *arg)

{

    int i;

    for(i = 0;i < 3;i++)

        {

            sem_wait(&sem_id2);

            printf("thread_black have the semaphore \n");

            number--;

            printf("number = %d\n",number);

            sem_post(&sem_id1);

            sleep(1);

        }

}

int main(int argc,char *argv[])

{

    number = 0;

    pthread_t id1, id2;

    sem_init(&sem_id1, 0, 1); // 空闲的

    sem_init(&sem_id2, 0, 0); // 忙的

    pthread_create(&id1,NULL,thread_white_fun, NULL);

    pthread_create(&id2,NULL,thread_black_fun, NULL);

    pthread_join(id1,NULL);

    pthread_join(id2,NULL);

    printf("main,,,\n");

    return 0;

}

void *produce(void *arg) 

{ 

    int i; 

    printf("\nproduce is called.\n"); 

    for(i=0;i<nitems;i++) 

    {       

        sem_wait(shared.nempty); //判断是否有空槽,有的将其减少1      

        sem_wait(shared.mutex);  //锁住槽位,对于多个生产者的时候有必要,单个生产者没有必要 

        printf("\nproduced a new item %d:",i); 

        scanf("%d",&shared.buff[i%NBUFF]);

        sleep(1);

        sem_post(shared.mutex);  //释放锁 

        sem_post(shared.nstored);  //缓冲区中条目数加1 

    } 

    return NULL; 

} 

void *consume(void *arg) 

{ 

    int   i; 

    printf("\nconsumer is called.\n"); 

    for(i=0;i<nitems;i++) 

    {       

        sem_wait(shared.nstored);  //判断缓冲区中是否有条目,有的话将条目数减少1 

        sem_wait(shared.mutex);     //锁住缓冲区,对多个消费者有必要,对单个消费者没必要

        if(shared.buff[i % NBUFF] != i) 

        printf("\nremoved %d item %d.",i,shared.buff[i% NBUFF]); 

        sleep(1);

        sem_post(shared.mutex);  //释放锁 

        sem_post(shared.nempty); //将缓冲区中的空槽数目加1 

    } 

    return NULL;

}

//生产者 消费者

shared.nstored  对缓冲区有多少进行判断

然后互斥访问

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

#include <errno.h>

#include <unistd.h>

int myglobal=10;

void *thread_function(void *arg)

{

    int i,j;

    for(i = 0; i <20; i++){

        j = myglobal;

        j++;

        printf(".");

        fflush(stdout);

        sleep(1);

        myglobal = j;

    }

    return NULL;

}

int main(){

    pthread_t mythread;

    int i;

    if( pthread_create(&mythread,NULL,thread_function,NULL))

    {

        printf("error creating thread!\n");

        abort();

    }

    for(i = 0; i <20; i++)

    {

        myglobal++;

        printf("O");

        fflush(stdout);

        sleep(1);

    }

    if( pthread_join(mythread,NULL))

    {

        printf("error joining thread!\n");

        abort();

    }

    printf("\nmyglobal equald %d\n",myglobal);

    exit(0);

}

//o . 交错输出

##signal

#include <signal.h>

#include <stdio.h>

#include <unistd.h>

void ouch(int sig)

{

    printf("OUCH! - I got signal %d\n", sig);

  //恢复SIGINT信号的处理动作

   (void) signal(SIGINT, SIG_DFL); 

}

int main()

{

    //设置SIGINT信号的处理动作为响应ouch函数

    //(void) signal(SIGINT, SIG_IGN);

    (void) signal(SIGINT, ouch);  

    //主函数每隔1秒输出字符串

    while(1) {

         printf("Hello World!\n");

         sleep(1);

      }

}

//第一次收到signal2,即SIGINT,因为存在(void)signal(SIGINT,ouch),会运行ouch函数然后打印SIGINT -  got signal 2,然后在运行signal第二次会收到signal2即终止程序。

SIGINT --- 2

SIG_DFL ---- 退出

#include <signal.h>

#include <unistd.h>

#include <stdio.h>

void sigroutine(int sig)

{ 

    switch (sig) {

        case 2:

            printf("Get a signal -- SIGINT\n");break;

        case 3:

            printf("Get a signal -- SIGQUIT\n");break;

    }

    return;

}

int main() {

    printf("process id is %d\n ",getpid()); 

    (void) signal(SIGINT, sigroutine);  //ctr+c

    (void) signal(SIGQUIT, sigroutine);  //ctr+

    for (;;);

}

//根据按下的键盘信号作出相对应的信号反应

#include<unistd.h>

#include<signal.h>

#include <stdio.h>

void handler() {

    printf("hello\n");

}

main()

{

     int i;

     signal(SIGALRM,handler);

     alarm(3);

     for(i=1;i<7;i++){

           printf("sleep %d ...\n",i);

           sleep(1);

     }

}

//设置时钟信号到3s的时候使用函数handler

#include <signal.h>

#include <unistd.h>

#include <stdio.h>

#include <sys/time.h>

int sec;

void sigroutine(int signo) {

    switch (signo) {

        case SIGALRM:printf("Catch a signal -- SIGALRM \n");break;

        case SIGVTALRM:printf("Catch a signal -- SIGVTALRM \n");break;

    }

    return;

}

int main()

{

    struct itimerval value,ovalue,value2;

    sec = 5;

    printf("process id is %d \n",getpid());

    signal(SIGALRM, sigroutine);

    signal(SIGVTALRM, sigroutine);

    value.it_value.tv_sec = 1;//单位为s

    value.it_value.tv_usec = 0;//单位为us

    value.it_interval.tv_sec = 1;//延迟的s数 //s

    value.it_interval.tv_usec = 0;

    setitimer(ITIMER_REAL, &value, &ovalue);//以当前操作时间

    value2.it_value.tv_sec = 0;

    value2.it_value.tv_usec = 500000;

    value2.it_interval.tv_sec = 0;

    value2.it_interval.tv_usec = 500000;//us

    setitimer(ITIMER_VIRTUAL, &value2, &ovalue);//以花费的时间

    for (;;) ;

}

//value 1s的时候执行

//value2 0.5s的时候执行

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

#include <signal.h>

static int alarm_fired = 0;            //闹钟未设置

//模拟闹钟

void ding(int sig)

{

    alarm_fired = 1;               //设置闹钟

}

int main()

{

    int pid;

    printf("alarm application starting\n");

    if((pid = fork( )) == 0) 

    {     //子进程5秒后发送信号SIGALRM给父进程

        sleep(5);

        kill(getppid(), 16);

        exit(0);

    }

//父进程安排好捕捉到SIGALRM信号后执行ding函数

    printf("waiting for alarm to go off\n");

    (void) signal(16, ding); 

    pause();           //挂起父进程,直到有一个信号出现

    if (alarm_fired)

        printf("Ding!\n");

    printf("done\n");

    wait(0);

    if (alarm_fired)

        printf("Ding!\n");

}

//kill()

使用方法:int kill(pid_t pid, int sig);

pid可能选择有以下四种:

1\. pid大于零时,pid是信号欲送往的进程的标识。

2\. pid等于零时,信号将送往所有与调用kill()的那个进程属同一个使用组的进程。

3\. pid等于-1时,信号将送往所有调用进程有权给其发送信号的进程,除了进程1(init)。

4\. pid小于-1时,信号将送往以 -pid 为组标识的进程。

#include<unistd.h>

#include<signal.h>

#include<sys/types.h>

#include<sys/wait.h>

#include<stdlib.h>

#include <stdio.h>

main()

{

    pid_t pid;

    int status;

    if(!(pid= fork())){

        //子进程

        printf("child process start!\n");

        sleep(6);

        printf("child process end !\n");

        exit(0);

    }

    else{

        //父进程

        printf("send signal to child process (%d) \n",pid);

        sleep(2);

        kill(pid ,SIGABRT);

        wait(&status);

        if(WIFSIGNALED(status))

        printf("chile process receive signal %d\n",WTERMSIG(status));

    }

}

#include <stdio.h>

#include <signal.h>

#include <unistd.h>

#include <stdlib.h>

int wait_mark;

void waiting( ),stop( );

int main( )

{

    int p1,p2;

    signal(SIGINT,stop);            

    while((p1=fork())==-1);

    if(p1>0) 

    { 

        while((p2=fork())==-1);

        if(p2>0)  

        {           

            wait_mark=1;

            waiting( );

            kill(p1,16);

            kill(p2,17);

            wait(0);

            wait(0);

            printf("parents is killed \n");

            exit(0);

        }

        else     

        {

            wait_mark=1;

            signal(17,stop);

            waiting();  

            lockf(1,F_LOCK,100);//锁定

            printf("P2 is killed by parent 1\n");

            fflush(stdout);

            sleep(1);

            printf("P2 is killed by parent 2\n");

            fflush(stdout);

            lockf(1,F_ULOCK,100);//解锁

            exit(0);

        }

    }

    else       

    {

        wait_mark=1;

        signal(16,stop);

        waiting( ); 

        lockf(1,F_LOCK,100);

        printf("P1 is killed by parent 1\n");

        fflush(stdout);

        sleep(1);

        printf("P1 is killed by parent 2\n");

        fflush(stdout);

        lockf(1,F_ULOCK,100);

        exit(0);    

    }

}

void   waiting( )

{

    while(wait_mark!=0);

}

void  stop( )

{

    wait_mark=0;

}

#include <stdio.h>

#include <signal.h>

#include <sys/types.h>

#include <unistd.h>

void new_op(int,siginfo_t*,void*);

int main(int argc,char**argv)

{

    struct sigaction act;

    int sig;

    sig=atoi(argv[1]);

    sigemptyset(&act.sa_mask);

    act.sa_flags=SA_SIGINFO;

    act.sa_sigaction=new_op;//处理

    if(sigaction(sig,&act,NULL) < 0)

    {

        printf("install sigal error\n");

    }

    while(1)

    {

        sleep(3);

        printf("wait for the signal\n");

    }

}

void new_op(int signum,siginfo_t *info,void *myact)

{

    printf("receive signal %d\n", signum);

    sleep(1);

}

//给信号signum设置新的信号处理函数act, 同时保留该信号原有的信号处理函数oldact

--?

#include <stdio.h>

#include <string.h>

#include <signal.h>

#include <sys/types.h>

#include <unistd.h>

void new_op(int,siginfo_t*,void*);

int main(int argc,char**argv)

{

    struct sigaction act;

    union sigval mysigval;

    int i;

    int sig;

    pid_t pid;

    char data[10];

    memset(data,0,sizeof(data));

    for(i=0;i < 10;i++)

        data[i]='$';

    mysigval.sival_ptr=data;

    sig=atoi(argv[1]);

    pid=getpid();

    sigemptyset(&act.sa_mask);

    act.sa_sigaction = new_op;//三参数信号处理函数

    act.sa_flags=SA_SIGINFO;//信息传递开关,允许传送参数信息给new_op

    if(sigaction(sig,&act,NULL) < 0)

    {

        printf("install sigal error\n");

    }

    while(1){

        sleep(2);

        printf("wait for the signal\n");

        sigqueue(pid,sig,mysigval);//向本进程发送信号,并传递附加信息

    }

}

void new_op(int signum,siginfo_t *info,void *myact)//三参数信号处理函数的实现

{

    int i;

    for(i=0;i<10;i++){

        printf("%c ",(*( (char*)((*info).si_ptr)+i)));

    }

    printf("\nhandle signal %d over;\n\n",signum);

}

//使用SA_SIGINFO使得处理函数被替代,然后使得在处理过程中,函数的处理由new_OP来进行。

#memery 共享内存

#include<unistd.h>

#include<sys/ipc.h>

#include<sys/shm.h>

#include<errno.h>

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#define KEY 1234                              /*键*/

#define SIZE 1024                             /*欲建立的共享内存的大小*/

int main()

{

    int shmid;

    char *shmaddr;

    struct shmid_ds buf;

    shmid=shmget(KEY,SIZE,IPC_CREAT|0600);         /*建立共享内存*/

    if(shmid==-1)

    {

        printf("create share memory failed:%s",strerror(errno));

        return 0;

    }

    if(fork( )==0)

    {                                   /*子进程*/

        sleep(2);   

        shmaddr=(char*)shmat(shmid,NULL,0);   /*系统自动选择一个地址连接*/

        if(shmaddr==(void*)-1)

        {

            printf("connect to the share memory failed:%s",strerror(errno));

            return 0;

        }

        /*向共享内存内写数据*/

        strcpy(shmaddr,"hello,i am huj\n");

        shmdt(shmaddr);                            /*断开共享内存*/

        exit(0);

    }else

    {                                          /*父进程*/

        wait(0);

        shmctl(shmid,IPC_STAT,&buf);     /*取得共享内存的相关信息*/

        printf("size of the share memory: shm_segsz=%dbytes\n",buf.shm_segsz);

        printf("process id of the creator:shm_cpid=%d\n",buf.shm_cpid);

        printf("process id of the last operator:shm_lpid=%d\n\n",buf.shm_lpid);

        shmaddr=(char*)shmat(shmid,NULL,0);      /*系统自动选择一个地址连接*/

        if(shmaddr==(void*)-1)

        {

            printf("connect the share memory failed:%s",strerror(errno));

            return 0;

        }

        printf("print the content of the share memory:\t");

        printf("%s\n",shmaddr);

        shmdt(shmaddr);   

                                /*断开共享内存*/

        shmctl(shmid,IPC_STAT,&buf);     /*取得共享内存的相关信息*/

        printf("process id of the last operator:shm_lpid=%d\n",buf.shm_lpid);

        /*当不再有任何其它进程使用该共享内存时系统将自动销毁它*/

        shmctl(shmid,IPC_RMID,NULL);

    }

}

- read and write

/*read.c*/

#include <stdio.h>

#include <stdlib.h>

#include <sys/shm.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <sys/ipc.h>

#define SHMSZ     27

int main()

{

    int shmid;

    key_t key;

    char *shm, *s;

char c;

    key = 5679;

    if ((shmid = shmget(key, SHMSZ, 0666)) < 0) {

                perror("shmget");

                exit(1);

        }

    if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {

                perror("shmat");

                exit(1);

    }

    for (s = shm; *s != '\0'; s++)

                putchar(*s);

        putchar('\n');

        //exit(0);

    c = getchar();

    shmctl(shmid,IPC_RMID,NULL);

}

/*write.c*/

#include <stdio.h>

#include <sys/shm.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <stdlib.h>

#define SHMSZ     27

int main()

{

    char c;

    int shmid;

    key_t key;

    char *shm, *s;

    key = 5679;

   if ((shmid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0) {

                perror("shmget");

                exit(1);

        }

    if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {

                perror("shmat");

                exit(1);

        }

    s = shm;

    for (c = 'a'; c <= 'z'; c++)

                *s++ = c;

    *s = '\0';   

   c = getchar();

}

//shmctl(shmid,IPC_RMID,NULL); //销毁记住

// shmat(shmid, NULL, 0)) 记住

//shmget(key, SHMSZ, IPC_CREAT | 0666))

//semctl(sem_id, 0, SETVAL, sem_union)

#include <unistd.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <sys/sem.h>

#if defined (__GNU_LIBRARY__)&& !defined (_SEM_SEMUN_UNDEFINED) 

/* union semun is defined by including <sys/sem.h> */ 

#else 

/* according to X/OPEN we have to define it ourselves */ 

union semun{ 

    int val; /* value for SETVAL */ 

    struct semid_ds *buf; /* buffer for IPC_STAT,IPC_SET */ 

    unsigned short int *array; /* array for GETALL,SETALL */ 

    struct seminfo *__buf; /* buffer for IPC_INFO */ 

}; 

#endif 

static int sem_id = 0;

static int set_semvalue();

static void del_semvalue();

static int semaphore_p();

static int semaphore_v();

int main(int argc, char *argv[])

{

    char message = '.';

    int i = 0;

    // 创建信号量

    sem_id = semget((key_t) 1234, 1, 0666 | IPC_CREAT);

    if (argc > 1)

    {

        // 程序第一次被调用,初始化信号量

        if (!set_semvalue())

        {

            fprintf(stderr, "Failed to initialize semaphore\n");

            exit(EXIT_FAILURE);

        }

        // 设置要输出到屏幕中的信息,即其参数的第一个字符

        message = 'O';

        sleep(2);

    }

    for (i = 0; i < 10; ++i)

    {

        if (!semaphore_p())

        {

            exit(EXIT_FAILURE);

        }

        printf("%c", message);      

        fflush(stdout);

        sleep(rand() % 3);      

        printf("%c", message);

        fflush(stdout);

        sleep(rand() % 2);

        if (!semaphore_v())

        {

            exit(EXIT_FAILURE);

        }       

    }

    //sleep(3);

    printf("\n%d - finished\n", getpid());

    if (argc > 1)

    {

        // 如果程序是第一次被调用,则在退出前删除信号量

        sleep(3);

        del_semvalue();

    }

    exit(EXIT_SUCCESS);

}

static int set_semvalue()

{

    // 用于初始化信号量,在使用信号量前必须这样做

    union semun sem_union;

    sem_union.val = 1;

    if (semctl(sem_id, 0, SETVAL, sem_union) == -1)

    {

        return 0;

    }

    return 1;

}

static void del_semvalue()

{

    // 删除信号量

    union semun sem_union;

    if (semctl(sem_id, 0, IPC_RMID, sem_union) == -1)

    {

        fprintf(stderr, "Failed to delete semaphore\n");

    }

}

static int semaphore_p()

{

    // 对信号量做减1操作,即等待P(sv)

    struct sembuf sem_b;

    sem_b.sem_num = 0;

    sem_b.sem_op = -1;//P()

    sem_b.sem_flg = SEM_UNDO;

    if (semop(sem_id, &sem_b, 1) == -1)

    {

        fprintf(stderr, "semaphore_p failed\n");

        return 0;

    }

    return 1;

}

static int semaphore_v()

{

    // 这是一个释放操作,它使信号量变为可用,即发送信号V(sv)

    struct sembuf sem_b;

    sem_b.sem_num = 0;

    sem_b.sem_op = 1; // V()

    sem_b.sem_flg = SEM_UNDO;

    if (semop(sem_id, &sem_b, 1) == -1)

    {

        fprintf(stderr, "semaphore_v failed\n");

        return 0;

    }

    return 1;

}

//通过信号量pv 来进行模拟;

  当op>0, 表示p操作

  当op<0,表示v操作

-- ?

/**** reader_writer1.c 一个利用共享内存进行进程通信的程序 ****/ 

#include <stdio.h> 

#include <sys/types.h> 

#include <sys/ipc.h> 

#include <sys/sem.h> 

#include <sys/shm.h> 

#include <stdlib.h> 

#include <errno.h> 

#include <string.h> 

#include <signal.h> 

/* The union for semctl may or may not be defined for us.This code,defined 

 in linux's semctl() manpage,is the proper way to attain it if necessary */ 

#if defined (__GNU_LIBRARY__)&& !defined (_SEM_SEMUN_UNDEFINED) 

/* union semun is defined by including <sys/sem.h> */ 

#else 

/* according to X/OPEN we have to define it ourselves */ 

union semun{ 

    int val; /* value for SETVAL */ 

    struct semid_ds *buf; /* buffer for IPC_STAT,IPC_SET */ 

    unsigned short int *array; /* array for GETALL,SETALL */ 

    struct seminfo *__buf; /* buffer for IPC_INFO */ 

}; 

#endif 

#define SHMDATASIZE 1000 

#define BUFFERSIZE (SHMDATASIZE - sizeof(int)) 

#define SN_READ 0 

#define SN_WRITE 1 

int Semid = 0; /* 用于最后删除这个信号量 */ 

void reader(void); 

void writer(int shmid); 

void delete(void); 

void sigdelete(int signum); 

void locksem(int semid,int semnum); 

void unlocksem(int semid,int semnum); 

void waitzero(int semid,int semnum); 

void write(int shmid,int semid,char *buffer); 

int mysemget(key_t key,int nsems,int semflg); 

int mysemctl(int semid,int semnum,int cmd,union semun arg); 

int mysemop(int semid,struct sembuf *sops,unsigned nsops); 

int myshmget(key_t key,int size,int shmflg); 

void *myshmat(int shmid,const void *shmaddr,int shmflg); 

int myshmctl(int shmid,int cmd,struct shmid_ds *buf); 

int main(int argc,char *argv[]){ 

     /* 没有其它的参数,则为 reader */ 

    if(argc < 2){ 

        reader(); 

    }else{ 

        writer(atoi(argv[1])); 

    } 

    return 0; 

} 

void reader(void){ 

    union semun sunion; 

    int semid,shmid; 

    void *shmdata; 

    char *buffer; 

    /* 首先:我们要创建信号量 */ 

    semid = mysemget(IPC_PRIVATE,2,SHM_R|SHM_W);     

    Semid = semid; 

    /* 在进程离开时,删除信号量 */ 

    atexit(&delete); 

    signal(SIGINT,&sigdelete); 

    /* 信号量 SN_READ 初始化为 1(锁定),SN_WRITE 初始化为 0(未锁定)*/ 

    sunion.val = 1; 

    mysemctl(semid,SN_READ,SETVAL,sunion); 

    sunion.val = 0; 

    mysemctl(semid,SN_WRITE,SETVAL,sunion); 

    /* 现在创建一块共享内存 */ 

    shmid = myshmget(IPC_PRIVATE,SHMDATASIZE,IPC_CREAT|SHM_R|SHM_W); 

    /* 将该共享内存映射到进程的虚存空间 */ 

    shmdata = shmat(shmid,0,0); 

    /* 将该共享内存标志为已销毁的,这样在使用完毕后,将被自动销毁*/ 

    shmctl(shmid,IPC_RMID,NULL); 

    /* 将信号量的标识符写入共享内存,以通知其它的进程 */ 

    *(int *)shmdata = semid; 

    buffer = shmdata + sizeof(int); 

    printf("\n reader begin to run,and the id of share memory is %d ** \n",shmid); 

    /*********************************************************** 

    reader 的主循环

    ************************************************************/ 

    while(1){ 

        printf(" \n wait for the writer's output information ..."); 

        fflush(stdout); 

        locksem(semid,SN_WRITE); 

        printf(" finish \n");        

        printf(" received information: %s \n",buffer); 

        unlocksem(semid,SN_READ); 

    } 

} 

void writer(int shmid){ 

    int semid; 

    void *shmdata; 

    char *buffer; 

    /* 将该共享内存映射到进程的虚存空间 */ 

    shmdata = myshmat(shmid,0,0); 

    semid = *(int *)shmdata; 

    buffer = shmdata + sizeof(int); 

    printf(" \n writer begin to run,the id of share memory is %d, the semaphore is %d \n",shmid,semid); 

    /*********************************************************** 

    writer 的主循环

    ************************************************************/ 

    while(1){ 

        char input[3]; 

        printf("\n menu \n 1.send a message \n"); 

        printf(" 2.quit \n"); 

        printf("input your choice(1-2):"); 

        fgets(input,sizeof(input),stdin); 

        switch(input[0]){ 

            case '1':write(shmid,semid,buffer);break; 

            case '2':exit(0);break; 

        } 

    } 

} 

void delete(void){ 

    printf("\n quit; delete the semaphore %d \n",Semid); 

    /* 删除信号量 */ 

    if(semctl(Semid,0,IPC_RMID,0) == -1){ 

        printf("Error releasing semaphore.\n"); 

    } 

} 

void sigdelete(int signum){ 

    /* Calling exit will conveniently trigger the normal delete item. */ 

    exit(0); 

} 

void locksem(int semid,int semnum){ 

    struct sembuf sb; 

    sb.sem_num = semnum; 

    sb.sem_op = -1; 

    sb.sem_flg = SEM_UNDO; 

    mysemop(semid,&sb,1); 

} 

void unlocksem(int semid,int semnum){ 

    struct sembuf sb; 

    sb.sem_num = semnum; 

    sb.sem_op = 1; 

    sb.sem_flg = SEM_UNDO; 

    mysemop(semid,&sb,1); 

} 

void waitzero(int semid,int semnum){ 

    struct sembuf sb; 

    sb.sem_num = semnum; 

    sb.sem_op = 0; 

    sb.sem_flg = 0; /* No modification so no need to undo */ 

    mysemop(semid,&sb,1);  

} 

void write(int shmid,int semid,char *buffer){ 

    printf("\n wait for reader to read in information ..."); 

    fflush(stdout); 

    locksem(semid,SN_READ); 

    printf("finish \n");     

    printf("please input information: "); 

    fgets(buffer,BUFFERSIZE,stdin); 

    unlocksem(semid,SN_WRITE); 

} 

int mysemget(key_t key,int nsems,int semflg){ 

    int retval; 

    retval = semget(key,nsems,semflg); 

    if(retval == -1){ 

        printf("semget key %d,nsems %d failed: %s ",key,nsems,strerror(errno)); 

        exit(255); 

    }    

    return retval; 

} 

int mysemctl(int semid,int semnum,int cmd,union semun arg){ 

    int retval; 

    retval = semctl(semid,semnum,cmd,arg); 

    if(retval == -1){ 

        printf("semctl semid %d,semnum %d,cmd %d failed: %s",semid,semnum,cmd,strerror(errno)); 

        exit(255); 

    } 

    return retval; 

} 

int mysemop(int semid,struct sembuf *sops,unsigned nsops){ 

    int retval; 

    retval = semop(semid,sops,nsops); 

    if(retval == -1){ 

        printf("semop semid %d (%d operations) failed: %s",semid,nsops,strerror(errno)); 

        exit(255); 

    }    

    return retval; 

} 

int myshmget(key_t key,int size,int shmflg){ 

    int retval; 

    retval = shmget(key,size,shmflg); 

    if(retval == -1){ 

        printf("shmget key %d,size %d failed: %s",key,size,strerror(errno)); 

        exit(255); 

    }    

    return retval; 

} 

void *myshmat(int shmid,const void *shmaddr,int shmflg){ 

    void *retval; 

    retval = shmat(shmid,shmaddr,shmflg); 

    if(retval == (void*) -1){ 

        printf("shmat shmid %d failed: %s",shmid,strerror(errno)); 

        exit(255); 

    }    

    return retval; 

} 

int myshmctl(int shmid,int cmd,struct shmid_ds *buf){ 

    int retval; 

    retval = shmctl(shmid,cmd,buf); 

    if(retval == -1){ 

        printf("shmctl shmid %d,cmd %d failed: %s",shmid,cmd,strerror(errno)); 

        exit(255); 

    }    

    return retval; 

} 

//通过arc参数 大于2为writer进程,小于2或者默认为读者进程,通过pv操作进行模拟进程发送两端的结果。

/**** reader_writer2.c 改进的利用共享内存进行进程通信的程序 ****/ 

#include <stdio.h> 

#include <sys/types.h> 

#include <sys/ipc.h> 

#include <sys/sem.h> 

#include <sys/shm.h> 

#include <stdlib.h> 

#include <errno.h> 

#include <string.h> 

#include <signal.h> 

/* The union for semctl may or may not be defined for us.This code,defined 

 in linux's semctl() manpage,is the proper way to attain it if necessary */ 

#if defined (__GNU_LIBRARY__)&& !defined (_SEM_SEMUN_UNDEFINED) 

/* union semun is defined by including <sys/sem.h> */ 

#else 

/* according to X/OPEN we have to define it ourselves */ 

union semun{ 

    int val; /* value for SETVAL */ 

    struct semid_ds *buf; /* buffer for IPC_STAT,IPC_SET */ 

    unsigned short int *array; /* array for GETALL,SETALL */ 

    struct seminfo *__buf; /* buffer for IPC_INFO */ 

}; 

#endif 

#define SHMDATASIZE 1000 

#define BUFFERSIZE (SHMDATASIZE - sizeof(int)) 

#define SN_READ 0 

#define SN_WRITE 1 

#define SN_LOCK 2 

int Semid = 0; 

void reader(int shmid); 

void writer(int shmid); 

int masterinit(void); 

char *standardinit(int shmid,int *semid); 

void delete(void); 

void sigdelete(int signum); 

void locksem(int semid,int semnum); 

void unlocksem(int semid,int semnum); 

void waitzero(int semid,int semnum); 

void write(int shmid,int semid,char *buffer); 

int mysemget(key_t key,int nsems,int semflg); 

int mysemctl(int shmid,int semnum,int cmd,union semun arg); 

int mysemop(int semid,struct sembuf *sops,unsigned nsops); 

int myshmget(key_t key,int size,int shmflg); 

void *myshmat(int shmid,const void *shmaddr,int shmflg); 

int myshmctl(int shmid,int cmd,struct shmid_ds *buf); 

int main(int argc,char *argv[]){ 

    char selection[3]; 

    int shmid; 

    /* 没有参数,则为 master */ 

    if(argc < 2){ 

        shmid = masterinit(); 

    }else{ 

        shmid = atoi(argv[1]); 

    } 

    printf(" do you want a writer(1) or reader(2) ?"); 

    fgets(selection,sizeof(selection),stdin); 

    switch(selection[0]){ 

        case '1':writer(shmid); break; 

        case '2':reader(shmid);break; 

        default:printf(" invalid choice, quit \n"); 

    } 

    return 0; 

} 

void reader(int shmid){ 

    int semid; 

    char *buffer; 

    buffer = standardinit(shmid,&semid); 

    printf("\n reader begin to run,and the id of share memory is %d, semaphore id is %d \n",shmid,semid); 

    while(1){ 

        printf("\n wait for writer to input information ...\n"); 

        fflush(stdout); 

        locksem(semid,SN_WRITE); 

        printf("finish \n"); 

        printf("\nwait for locking semaphore SN_LOCK ...\n"); 

        fflush(stdout); 

        locksem(semid,SN_LOCK); 

        printf("finish \n"); 

        printf("\nreceived information: %s \n",buffer); 

        unlocksem(semid,SN_LOCK); 

        unlocksem(semid,SN_READ); 

    } 

} 

void writer(int shmid){ 

    int semid; 

    char *buffer; 

    buffer = standardinit(shmid,&semid); 

    printf("writer begin to run,the id of share memory is %d, semaphore id is %d \n",shmid,semid); 

    while(1){ 

        char input[3]; 

        printf("\n menu \n 1.send a message \n"); 

        printf(" 2.quit \n"); 

        printf("input your choice(1-2):"); 

        fgets(input,sizeof(input),stdin); 

        switch(input[0]){ 

            case '1':write(shmid,semid,buffer);break; 

            case '2':exit(0);break; 

        } 

    } 

} 

char *standardinit(int shmid,int *semid){ 

    void *shmdata; 

    char *buffer; 

    shmdata = myshmat(shmid,0,0); 

    *semid = *(int *)shmdata; 

    buffer = shmdata + sizeof(int); 

    return buffer; 

} 

int masterinit(void){ 

    union semun sunion; 

    int semid,shmid; 

    void *shmdata; 

    /* 首先:我们要创建信号量 */ 

    semid = mysemget(IPC_PRIVATE,3,SHM_R|SHM_W); 

    Semid = semid; 

    /* 当进程离开时,删除信号量 */ 

    atexit(&delete); 

    signal(SIGINT,&sigdelete); 

    /* 信号量 SN_READ 初始化为 1(锁定),SN_WRITE 初始化为 0(未锁定)*/ 

    /* 信号量 SN_LOCK 初始化为 1(锁定)*/ 

    sunion.val = 1; 

    mysemctl(semid,SN_READ,SETVAL,sunion); 

    mysemctl(semid,SN_LOCK,SETVAL,sunion); 

    sunion.val = 0; 

    mysemctl(semid,SN_WRITE,SETVAL,sunion); 

    /* 现在创建一块共享内存 */ 

    shmid = myshmget(IPC_PRIVATE,SHMDATASIZE,IPC_CREAT|SHM_R|SHM_W); 

    /* 将该共享内存映射进进程的虚存空间 */ 

    shmdata = myshmat(shmid,0,0); 

    /* 将该共享内存标志为已销毁的,这样在使用完毕后,将被自动销毁*/ 

    myshmctl(shmid,IPC_RMID,NULL); 

    /* 将信号量的标识符写入共享内存,以通知其它的进程 */ 

    *(int *)shmdata = semid; 

    printf("*** begin to run, and semaphore id is %d \n",shmid); 

    return shmid; 

} 

void delete(void){ 

    printf("\n quit; delete the semaphore %d \n",Semid); 

    if(semctl(Semid,0,IPC_RMID,0) == -1){ 

        printf("Error releasing semaphore. \n"); 

    } 

} 

void sigdelete(int signum){ 

    /* Calling exit will conveniently trigger the normal delete item. */ 

    exit(0); 

} 

void locksem(int semid,int semnum){ 

    struct sembuf sb; 

    sb.sem_num = semnum; 

    sb.sem_op = -1; 

    sb.sem_flg = SEM_UNDO; 

    mysemop(semid,&sb,1); 

} 

void unlocksem(int semid,int semnum){ 

    struct sembuf sb; 

    sb.sem_num = semnum; 

    sb.sem_op = 1; 

    sb.sem_flg = SEM_UNDO; 

    mysemop(semid,&sb,1); 

} 

void waitzero(int semid,int semnum){ 

    struct sembuf sb; 

    sb.sem_num = semnum; 

    sb.sem_op = 0; 

    sb.sem_flg = 0; /* No modification so no need to undo */ 

    mysemop(semid,&sb,1); 

} 

void write(int shmid,int semid,char *buffer){ 

    printf("\n wait for reader to read in information ..."); 

    fflush(stdout); 

    locksem(semid,SN_READ); 

    printf("finish; wait for locking semaphore SN_LOCK...\n"); 

    fflush(stdout); 

    locksem(semid,SN_LOCK); 

    printf("please input information:"); 

    fgets(buffer,BUFFERSIZE,stdin); 

    unlocksem(semid,SN_LOCK); 

    unlocksem(semid,SN_WRITE);  

} 

int mysemget(key_t key,int nsems,int semflg){ 

    int retval; 

    retval = semget(key,nsems,semflg); 

    if(retval == -1){ 

        printf("semget key %d,nsems %d failed: %s ",key,nsems,strerror(errno)); 

        exit(255); 

    } 

    return retval; 

} 

int mysemctl(int semid,int semnum,int cmd,union semun arg){ 

    int retval; 

    retval = semctl(semid,semnum,cmd,arg); 

    if(retval == -1){ 

        printf("semctl semid %d,semnum %d,cmd %d failed: %s",semid,semnum,cmd,strerror(errno)); 

        exit(255); 

    } 

    return retval; 

} 

int mysemop(int semid,struct sembuf *sops,unsigned nsops){ 

    int retval; 

    retval = semop(semid,sops,nsops); 

    if(retval == -1){ 

        printf("semop semid %d (%d operations) failed: %s",semid,nsops,strerror(errno)); 

        exit(255); 

    } 

    return retval; 

}

int myshmget(key_t key,int size,int shmflg){ 

    int retval; 

    retval = shmget(key,size,shmflg); 

    if(retval == -1){ 

        printf("shmget key %d,size %d failed: %s",key,size,strerror(errno)); 

        exit(255); 

    }    

    return retval; 

} 

void *myshmat(int shmid,const void *shmaddr,int shmflg){ 

    void *retval; 

    retval = shmat(shmid,shmaddr,shmflg); 

    if(retval == (void*) -1){ 

        printf("shmat shmid %d failed: %s",shmid,strerror(errno)); 

        exit(255); 

    }    

    return retval; 

} 

int myshmctl(int shmid,int cmd,struct shmid_ds *buf){ 

    int retval; 

    retval = shmctl(shmid,cmd,buf); 

    if(retval == -1){ 

        printf("shmctl shmid %d,cmd %d failed: %s",shmid,cmd,strerror(errno)); 

        exit(255); 

    }    

    return retval; 

} 

首先可以选择读者和写者身份,而不是通过arc进行判断

此时,可以选择是否输入id共享量,若有arc,则往该地区写入或者读取数据,否则 重新建立一块新的地区进行读写。

##msg 消息队列

#include <stdio.h>

#include <sys/types.h>

#include <sys/msg.h>

#include <sys/ipc.h>

#include <stdlib.h>

#define MSGKEY 75

struct msgform

{

    long mtype;

    char mtext[1000];

}msg;

int msgqid;

void server( )

{

    /*创建75#消息队列*/

    msgqid=msgget(MSGKEY,0777|IPC_CREAT); 

    do 

    {

        /*接收消息*/

        msgrcv(msgqid,&msg,1030,0,0);

        printf("(server)received:%s\n",msg.mtext);

    }while(msg.mtype!=1);

    /*删除消息队列,归还资源*/

    msgctl(msgqid,IPC_RMID,0);

    exit(0);

}

main( )

{

    server( );

}

#include <stdio.h>

#include <sys/types.h>

#include <sys/msg.h>

#include <sys/ipc.h>

#include <stdlib.h>

#define MSGKEY 75

struct msgform

{

    long mtype;

    char mtext[1000];

}msg;

int msgqid;

void client()

{

    int i; 

    /*打开75#消息队列*/

    msgqid=msgget(MSGKEY,0777); 

    for(i=10;i>=1;i--)

    {

        msg.mtype=i;

        scanf("%s",msg.mtext);

        //printf("(client)sent\n");

        /*发送消息*/

        msgsnd(msgqid,&msg,1024,0); 

    }

    exit(0);

}

main( )

{

    client( );

}

##管道

#include<fcntl.h>

#include <stdio.h>

#include <stdlib.h>

int  fdrd,fdwt;

char    c;

rdwrt( )

{

    for( ; ; ){

        if(read(fdrd,&c,1)!=1)  return;

        sleep(rand()%4);

        write(fdwt,&c,1);

    }

}

main(int argc,char *argv[])

{

    if(argc!=3){

        exit(1);

    }

    if((fdrd=open(argv[1],O_RDONLY))==-1)

    {

        exit(1);

    }

    if((fdwt=creat(argv[2],0666))==-1)

    {

        exit(1);

    }

    fork( );    

    rdwrt( );               //两个进程执行同样的代码

    exit(0);

}

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

int main( )

{

    int data_processed;

    int file_pipes[2];

    char buffer[100];

    pid_t fork_result;

    if ( pipe(file_pipes) == 0){

        fork_result = fork();

        if (fork_result == -1) { 

            fprintf(stderr, "Fork failure");

            exit(EXIT_FAILURE);

        }

        if (fork_result == 0) {                             //子进程

            //sleep(1);

            data_processed = read(file_pipes[0], buffer, BUFSIZ);

            printf("child:Read %d bytes: %s\n", data_processed, buffer);

            sleep(1);

            exit(EXIT_SUCCESS);

        }

        else {                                         //父进程

            printf("input a string:");

            scanf("%s",buffer);

            data_processed = write(file_pipes[1], buffer,strlen(buffer));

            wait(0);

            printf("parent:Wrote %d bytes\n", data_processed);

        }

    }

}

#include <stdio.h>

#include <stdlib.h>

#define MAXSTRS 5

int  main( )

{

    int cntr;

    FILE *pipe_fp;

    char *strings[MAXSTRS] = { "echo", "bravo", "alpha","charlie", "delta"};

    if (( pipe_fp = popen("sort", "w")) == NULL){          //打开管道写数据

        perror("popen");

        exit(1);

    }

    for(cntr=0; cntr<MAXSTRS; cntr++) {

        fputs(strings[cntr], pipe_fp);

        fputc('\n', pipe_fp);

    }

    pclose(pipe_fp);                                  //关闭管道

    return(0);

}

//使用文件系统制作的管道

--?

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

int main()

{

        pid_t p1;

        pid_t p2;

        char *argv1[]={"echo","good good morning",0};

    //  char *argv2[]={"sed","s/good/hi/",0};

        char *argv2[]={"sed","s/good/hi/g",0};

        int fd[2];

        if(pipe(fd)<0)printf("create pipe erorr");

        if(p1=fork()==0)

        {

            close(fd[0]);

            close(1);

            dup(fd[1]);

            close(fd[1]);//sleep(3);

            if(execvp("echo",argv1)==-1)

                printf("come on");

            sleep(1);

        }

        if(p2=fork()==0)

        {

            close(fd[1]);

            close(0);

            dup(fd[0]);

            close(fd[0]);//sleep(3);

            execvp("sed",argv2);

            sleep(1);

        }

        else 

        {

            close(fd[0]);

            close(fd[1]);

            wait(NULL);

            wait(NULL);

        }

        return 0;

        }

#include<stdio.h>

#include<unistd.h>

#include <stdlib.h>

int main()

{

        pid_t pid1,pid2;

        char *argv1[]={"pstree","-a",0};

        char *argv2[]={"grep","login",0};

        int fd[2];

        if(pipe(fd)<0)printf("create pipe erorr");

        if(pid1=fork()==0)

        {

            close(fd[0]);

            close(1);

            dup(fd[1]);

            close(fd[1]);

            if(execvp("pstree",argv1)==-1)

                printf("come on");

        }

        if(pid2=fork() ==0)

        {

            close(fd[1]);

            close(0);

            dup(fd[0]);

            close(fd[0]);

            execvp("grep",argv2);

        }

        else 

        {

            close(fd[0]);

            close(fd[1]);

            wait(NULL);

            wait(NULL);

        }

        return 0;

        }

#include <unistd.h>

#include <signal.h>

#include <stdio.h>

#include <stdlib.h>

int pid1,pid2; 

main( )

{ 

        int fd[2];

        char outpipe[100],inpipe[100];

        pipe(fd);                          /*¥¥Ω®"ª∏ˆπ‹µ¿*/

        while ((pid1=fork( )) == -1);

        if(pid1 == 0)

        {   

                //lockf(fd[1],1,0);

                /*∞--- ‰≥ˆ¥Æ∑≈»Î ˝◊Èoutpipe÷--*/

                sprintf(outpipe,"child 1 %d process is sending message!" , getpid()); 

                write(fd[1],outpipe,50);     /*œÚπ‹µ¿--¥≥§Œ™50◊÷Ω⁄µƒ¥Æ*/

                sleep(1);                 /*◊'Œ"◊Ë»˚1√Î*/

                //lockf(fd[1],0,0);

                exit(0);

        }

        else

        {

                while((pid2=fork( ))==-1);

                if(pid2==0)

                {   

                        //lockf(fd[1],1,0);           /*ª-≥‚*/

                        sprintf(outpipe,"child 2 %d process is sending message!" , getpid());

                        write(fd[1],outpipe,50);

                        sleep(1);

                        //lockf(fd[1],0,0);

                        exit(0);

                }

                else

                {   

                        //wait(0);              /*Õ¨≤Ω*/

                        read(fd[0],inpipe,50);   /*¥"π‹µ¿÷--∂¡≥§Œ™50◊÷Ω⁄µƒ¥Æ*/

                        printf("%s\n",inpipe);

                        //wait(0);

                        read(fd[0],inpipe,50);

                        printf("%s\n",inpipe);

                        return 0;

                }

        }

}

父子孙三代

父亲打印儿子 孙子write的消息

最后修改:2019 年 06 月 24 日 09 : 32 PM
如果觉得我的文章对你有用,请随意赞赏

发表评论

© 2018-2019 Copyright   | 浙ICP备18047860号-1| SiteMap