Linux下多进程多线程混合开发框架

2019-07-13 06:56发布

    多进程和多线程的概念相信大家都大致清楚,就不去百度copy了。这里引用一个比喻来描述下多进程和多线程:

    

   多进程是立体交通系统,虽然造价高,上坡下坡多耗点油,但是不堵车。

   多线程是平面交通系统,造价低,但红绿灯太多,老堵车。

   我们现在都开跑车,油(主频)有的是,不怕上坡下坡,就怕堵车。

    在多进程开发中,每个进程互相独立,不影响主程序的稳定性,子进程崩溃没关系;最好是多进程和多线程结合,即根据实际的需要,每个CPU开启一个子进程,这个子进程开启多线程可以为若干同类型的数据进行处理。

    需要提及的一点是,首先对于不同进程的线程而言,他们没有什么关系的(代码段、数据段等都不同),所以不能通过全局变量来通信。但是对于同一进程内的线程,他们是可以通过全局变量来通信的。同一进程内的线程,他们都共享进程的代码段、数据段、BSS段。页目录和页表应该是使用进程的页目录和页表。

 

linux fork()子父进程变量共享情况,共享代码段

子进程会拷贝父进程的所有资源,变量。

注意:子进程拷贝了父进程数据空间、堆、栈等资源的副本,

父子进程间不共享这些存储空间,共享的空间只有代码段,

子进程修改一个全局变量,父进程的这个全局变量不会改变,因为是一个副本。

 

   所以进程之间可以通过共享内存、消息队列等方式进行通信。在实际的项目开发中,这个用得很多,现在也有一些不错的开源库提供给大家调用。

   

   下面给出一个多进程结合多线程的开发案例,供大家参考:

#include #include #include #include #include #include #include #include #define NUM_THREADS 6 #define ID_BASE 101 #define CHAIR_COUNT 3 #define STUDENT_COUNT 25 #define MAX_MEETING_DURATION 5 #define OFFICE_HOUR_DURATION 60 #define BSIZE 4 #define NUMITEMS 30 typedef struct { char buf[BSIZE]; int occupied; int nextin, nextout; pthread_mutex_t mutex; pthread_cond_t more; pthread_cond_t less; } buffer_t; buffer_t buffer; #define NUM_THREADS2 2 pthread_t tid[NUM_THREADS2]; /* array of thread IDs */ #define NTHREADS 4 #define N 1000 #define MEGEXTRA 1000000 pthread_attr_t attr; #define NUM_THREADS5 8 char *messages[NUM_THREADS5]; //------------------------------------------------------------------------- /*进程1的线程*/ //-------------------------------------------------------------------------- int chairs[CHAIR_COUNT]; // circular buffer of chairs pthread_mutex_t chairMutex; // mutex protects chairs and wait count pthread_mutex_t printMutex; // mutex protects printing sem_t filledChairs; // professor waits on this semaphore struct itimerval profTimer; // professor's office hour timer time_t startTime; int in = 0, out = 0; int meetingId = 0; int arrivalsCount = 0; int waitCount = 0; int leavesCount = 0; int meetingsCount = 0; int parforeCount = 0; int firstPrint = 1; // Print a line for each event: // elapsed time // who is meeting with the professor // who is waiting in the chairs // what event occurred void print(char *event) { time_t now; time(&now); double elapsed = difftime(now, startTime); int min = 0; int sec = (int) elapsed; if (sec >= 60) { min++; sec -= 60; } // Acquire the mutex lock to protect the printing. pthread_mutex_lock(&printMutex); if (firstPrint) { printf("TIME | MEETING | WAITING | EVENT "); firstPrint = 0; } // Elapsed time. printf("%1d:%02d | ", min, sec); // Who's meeting with the professor. if (meetingId > 0) { printf("%5d |", meetingId); } else { printf(" |"); } // Acquire the mutex lock to protect the chairs and the wait count. pthread_mutex_lock(&chairMutex); int i = out; int j = waitCount; int k = 0; // Who's waiting in the chairs. while (j-- > 0) { printf("%4d", chairs[i]); i = (i+1)%CHAIR_COUNT; k++; } // Release the mutex lock. pthread_mutex_unlock(&chairMutex); // What event occurred. while (k++ < CHAIR_COUNT) printf(" "); printf(" | %s ", event); // Release the mutex lock. pthread_mutex_unlock(&printMutex); } // A student arrives. void studentArrives(int id) { char event[80]; arrivalsCount++; if (waitCount < CHAIR_COUNT) { // Acquire the mutex lock to protect the chairs and the wait count. pthread_mutex_lock(&chairMutex); // Seat a student into a chair. chairs[in] = id; in = (in+1)%CHAIR_COUNT; waitCount++; // Release the mutex lock. pthread_mutex_unlock(&chairMutex); sprintf(event, "Student %d arrives and waits", id); print(event); // Signal the "filledSlots" semaphore. sem_post(&filledChairs); // signal } else { leavesCount++; sprintf(event, "Student %d arrives and leaves", id); print(event); } } // The student thread. void *student(void *param) { int id = *((int *) param); // Students will arrive at random times during the office hour. sleep(rand()%OFFICE_HOUR_DURATION); studentArrives(id); return NULL; } int timesUp = 0; // 1 = office hour is over // The professor meets a student (or works on ParFore). void professorMeetsStudent() { // No student waiting, so work on ParFore language. if (waitCount == 0) { print("Professor works on ParFore"); parforeCount++; } if (!timesUp) { // Wait on the "filledChairs" semaphore for a student. sem_wait(&filledChairs); // Acquire the mutex lock to protect the chairs and the wait count. pthread_mutex_lock(&chairMutex); // Critical region: Remove a student from a chair. meetingId = chairs[out]; out = (out+1)%CHAIR_COUNT; waitCount--; // Release the mutex lock. pthread_mutex_unlock(&chairMutex); char event[80]; sprintf(event, "Professor meets with student %d", meetingId); print(event); // Meet with the student. sleep(rand()%MAX_MEETING_DURATION + 1); meetingsCount++; sprintf(event, "Professor finishes with student %d", meetingId); meetingId = 0; print(event); } } // The professor thread. void *professor(void *param) { print("Professor opens her door"); // Set the timer for for office hour duration. profTimer.it_value.tv_sec = OFFICE_HOUR_DURATION; setitimer(ITIMER_REAL, &profTimer, NULL); // Meet students until the office hour is over. do { professorMeetsStudent(); } while (!timesUp); print("Professor closes her door"); return NULL; } // Timer signal handler. void timerHandler(int signal) { timesUp = 1; // office hour is over } //-------------------------------------------------------------------------- /*进程3的线程*/ //-------------------------------------------------------------------------- void *PrintHello(void *threadid) { long tid; tid = (long)threadid; printf("Hello World!In process3, it's thread #%ld! ", tid); pthread_exit(NULL); //printf("goodbye! exit thread #%ld! ", tid); } //---------------------------------------------------------------------------- /*进程2的线程*/ //---------------------------------------------------------------------------- void * producer(void * parm) { char item[NUMITEMS]="IT'S A SMALL WORLD, AFTER ALL."; int i; printf("producer started. "); for(i=0;i