码迷,mamicode.com
首页 > 编程语言 > 详细

Linux多进程多线程例子

时间:2016-08-23 06:51:50      阅读:219      评论:0      收藏:0      [点我收藏+]

标签:

看了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 thread1(void *arg)
 28 {
 29     srand((long)arg + time(0));    //(时间 + 索引号)生成随机种子
 30     while (1) {
 31         sleep(rand() % 8 + 1);    //睡眠1~8s
 32         sem_pv(semid, -1);    //sem - 1,若sem = 1,不阻塞,若sem = 0,阻塞
 33         *shmaddr += 1;    //共享值 += 线程号
 34         printf("This is 1 thread, *shmaddr = %ld!!\n", *shmaddr);
 35         sem_pv(semid, +1);    //sem + 1,唤醒其他已经阻塞的线程
 36     }
 37     pthread_exit((arg));
 38 }
 39 
 40 void thread2(void *arg)
 41 {
 42     srand((long)arg + time(0));
 43     while (1) {
 44         sleep(rand() % 8 + 1);
 45         sem_pv(semid, -1);
 46         *shmaddr += 2;
 47         printf("This is 2 thread, *shmaddr = %ld!!\n", *shmaddr);
 48         sem_pv(semid, +1);
 49     }
 50     pthread_exit(arg);
 51 }
 52 
 53 void thread3(void *arg)
 54 {
 55     srand((long)arg + time(0));
 56     while (1) {
 57         sleep(rand() % 8 + 1);
 58         sem_pv(semid, -1);
 59         *shmaddr += 3;
 60         printf("This is 3 thread, *shmaddr = %ld!!\n", *shmaddr);
 61         sem_pv(semid, +1);
 62     }
 63     pthread_exit(arg);
 64 }
 65 
 66 void thread4(void *arg)
 67 {
 68     srand((long)arg + time(0));
 69     while (1) {
 70         sleep(rand() % 8 + 1);
 71         sem_pv(semid, -1);
 72         *shmaddr += 4;
 73         printf("This is 4 thread, *shmaddr = %ld!!\n", *shmaddr);
 74         sem_pv(semid, +1);
 75     }
 76     pthread_exit(arg);
 77 }
 78 
 79 void thread5(void *arg)
 80 {
 81     srand((long)arg + time(0));
 82     while (1) {
 83         sleep(rand() % 8 + 1);
 84         sem_pv(semid, -1);
 85         *shmaddr += 5;
 86         printf("This is 5 thread, *shmaddr = %ld!!\n", *shmaddr);
 87         sem_pv(semid, +1);
 88     }
 89     pthread_exit(arg);
 90 }
 91 
 92 void thread6(void *arg)
 93 {
 94     srand((long)arg + time(0));
 95     while (1) {
 96         sleep(rand() % 8 + 1);
 97         sem_pv(semid, -1);
 98         *shmaddr += 6;
 99         printf("This is 6 thread, *shmaddr = %ld!!\n", *shmaddr);
100         sem_pv(semid, +1);
101     }
102     pthread_exit(arg);
103 }
104 
105 void thread7(void *arg)
106 {
107     srand((long)arg + time(0));
108     while (1) {
109         sleep(rand() % 8 + 1);
110         sem_pv(semid, -1);
111         *shmaddr += 7;
112         printf("This is 7 thread, *shmaddr = %ld!!\n", *shmaddr);
113         sem_pv(semid, +1);
114     }
115     pthread_exit(arg);
116 }
117 
118 void thread8(void *arg)
119 {
120     srand((long)arg + time(0));
121     while (1) {
122         sleep(rand() % 8 + 1);
123         sem_pv(semid, -1);
124         *shmaddr += 8;
125         printf("This is 8 thread, *shmaddr = %ld!!\n", *shmaddr);
126         sem_pv(semid, +1);
127     }
128     pthread_exit(arg);
129 }
130 
131 typedef void (*thread)(void *arg);
132 #define PROJ_ID 8
133 int main(int argc, char const *argv[])
134 {
135     pid_t pid[4];
136     pthread_t thid[8];
137     thread fun[8] = {thread1, thread2, thread3, thread4, thread5, thread6, thread7, thread8};
138     key_t key;
139     int shmid;
140     int i;
141     long index;    //这里使用long是(void *)<---->long,long和指针占用内存大小(主机64bit)一样,否则gcc会报warnning
142     union semun {
143         int            val;
144         struct semid_ds        *buf;
145         unsigned short        *array;
146     } semopts;
147     
148     if ((key = ftok("." , PROJ_ID )) == -1) {
149         perror("ftok error");
150         exit(1);
151     }
152     if ((shmid = shmget(key, sizeof(long), IPC_CREAT | 0666)) == -1) {
153         perror("shmget error");
154         exit(1);
155     }
156     if ((shmaddr = (long *)shmat(shmid, NULL, 0)) == (long *) - 1) {
157         perror("shmat error");
158         exit(1);
159     }
160     *shmaddr = 0;    //初始化共享量
161 
162     if ((semid = semget(key, 1, IPC_CREAT | 0666)) == -1) {
163         perror("semget failed");
164         exit(1);
165     }
166     semopts.val = 1;    //信号量初始为1
167 
168     if (semctl(semid, 0, SETVAL, semopts) == -1) {
169         perror("semctl failed");
170         exit(1);
171     }
172     //创建4进程 & 8线程
173     for (i = 0; i < 4; ++i) {
174         pid[i] = fork();
175         if (pid[i] == 0) {
176             index = 2 * i;
177             if (pthread_create(&thid[index], NULL, (void *)fun[index], (void *)index) != 0) {
178                 perror("thread error");
179                 exit(1);
180             }
181             index++;
182             if (pthread_create(&thid[index], NULL, (void *)fun[index], (void *)index) != 0) {
183                 perror("thread error");
184                 exit(1);
185             }
186             sleep(1);
187             printf("This is %d process\n", i);
188             printf("Children‘s pid = %d, ppid = %d\n", getpid(), getppid());    
189             while (1)
190                 sleep(10);
191             exit(0);
192 
193         } else if (pid[i] < 0) {
194             perror("fork error");
195             exit(1);
196         }
197     }
198     //父进程退出,4个子进程成为孤儿进程
199     exit(0);
200 }

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

Linux多进程多线程例子

标签:

原文地址:http://www.cnblogs.com/kevinhwang/p/5797838.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!