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个子进程间不能共享累加结果,需要用进程共享量。同时涉及到多线程多进程的并发,需要用进程互斥量。