Linux多进程多线程例子

看了apue3,关于进程线程和进程间通信写了一个例子,方便自己理解相关知识,备忘。

  1 #include <stdlib.h>
  2 #include <stdio.h>
  3 #include <unistd.h>
  4 #include <pthread.h>
  5 #include <sys/types.h>
  6 #include <sys/ipc.h>
  7 #include <sys/shm.h>
  8 #include <sys/sem.h>
  9 
 10 //这里全局变量简化线程代码量而已,实际应该在线程获取这些变量再操作。
 11 long *shmaddr;    
 12 int semid;
 13 
 14 /**
 15  * 互斥量加或减
 16  * @param  semid 互斥量id
 17  * @param  pv    整数加,负数减
 18  */
 19 void sem_pv(int semid, short pv)
 20 {
 21     struct sembuf buf = {0, 0, 0};
 22     buf.sem_op = pv;
 23     buf.sem_num = 0;
 24     semop(semid, &buf, 1);
 25 }
 26 
 27 void *do_thread(void *arg)
 28 {
 29     long index = (long)arg;
 30     srand(index + time(0));    //(时间 + 索引号)生成随机种子
 31     while (1) {
 32         sleep(rand() % 8 + 1);    //睡眠1~8s
 33         sem_pv(semid, -1);    //sem - 1,若sem = 1,不阻塞,若sem = 0,阻塞
 34         *shmaddr += index;    //共享值 += 线程号
 35         printf("This is %ld thread, *shmaddr = %ld!!\n", index, *shmaddr);
 36         sem_pv(semid, +1);    //sem + 1,唤醒其他已经阻塞的线程
 37     }
 38     pthread_exit((arg));
 39 }
 40 
 41 #define PROJ_ID 8
 42 
 43 int main(int argc, char const *argv[])
 44 {
 45     pid_t pid[4];
 46     pthread_t thid[8];
 47     key_t key;
 48     int shmid;
 49     int i;
 50     long index;    //这里使用long是(void *)<---->long,long和指针占用内存大小(主机64bit)一样,否则gcc会报warnning
 51     union semun {
 52         int            val;
 53         struct semid_ds        *buf;
 54         unsigned short        *array;
 55     } semopts;
 56     
 57     if ((key = ftok("." , PROJ_ID )) == -1) {
 58         perror("ftok error");
 59         exit(1);
 60     }
 61     if ((shmid = shmget(key, sizeof(long), IPC_CREAT | 0666)) == -1) {
 62         perror("shmget error");
 63         exit(1);
 64     }
 65     if ((shmaddr = (long *)shmat(shmid, NULL, 0)) == (long *) - 1) {
 66         perror("shmat error");
 67         exit(1);
 68     }
 69     *shmaddr = 0;    //初始化共享量
 70 
 71     if ((semid = semget(key, 1, IPC_CREAT | 0666)) == -1) {
 72         perror("semget failed");
 73         exit(1);
 74     }
 75     semopts.val = 1;    //信号量初始为1
 76 
 77     if (semctl(semid, 0, SETVAL, semopts) == -1) {
 78         perror("semctl failed");
 79         exit(1);
 80     }
 81     //创建4进程 & 8线程
 82     for (i = 0; i < 4; ++i) {
 83         pid[i] = fork();
 84         if (pid[i] == 0) {
 85             index = 2 * i + 1;
 86             if (pthread_create(&thid[index], NULL, do_thread, (void *)index) != 0) {
 87                 perror("thread error");
 88                 exit(1);
 89             }
 90             index++;
 91             if (pthread_create(&thid[index], NULL, do_thread, (void *)index) != 0) {
 92                 perror("thread error");
 93                 exit(1);
 94             }
 95             sleep(1);
 96             printf("This is %d process\n", i);
 97             printf("Children's pid = %d, ppid = %d\n", getpid(), getppid());    
 98             while (1)
 99                 sleep(10);
100             exit(0);
101 
102         } else if (pid[i] < 0) {
103             perror("fork error");
104             exit(1);
105         }
106     }
107     //父进程退出,4个子进程成为孤儿进程
108     exit(0);
109 }

 

程序开启4进程8线程同时一起累加。线程可以用全局变量同步,但4个子进程间不能共享累加结果,需要用进程共享量。同时涉及到多线程多进程的并发,需要用进程互斥量。

posted @ 2016-08-23 02:58  Kevin_Hwang  阅读(583)  评论(0编辑  收藏  举报