First, design requirements
10 storage units are provided in the boundary buffer, and the data items put on / taken are set to 1 to 10 10 integration numbers. Each producer and consumers are required to operate the boundless buffer, all of the contents of the boundary buffer, the current pointer position, and the producer / consumer identifier.
Second, the experimental environment
Server: Linux
Client: Windows98 Telnet
Development language: c
Third, design ideas
Through this procedure, the simultaneous operation of producers and consumers is effectively controlled to control their operations for bounded buffers. The implementation of this program involves two major issues, one, how is it achieved production of mutual exclusion with consumers. Second, how to achieve the full use of 10 buffers.
The design thoughts of this program are generally as follows:
The boundless buffer is a one-dimensional length of 10, with two pointers in, out to control where the area is data, where to add data. IN with data to the last placed, OUT is used to point to the first data.
Therefore, 100% of the 10 buffer can be achieved by using the following algorithm.
IF (in == OUT && Buffer [in] == 0) / * Judgment is a buffer data, at which time IN pointer does not move backward * /
Buffer [in] = NextProduces;
Else / * Otherwise, the IN pointer is moved backward * /
{
Buffer [(in 1)% buffer_size] = nextProduces;
IN = (in 1)% buffer_size;
}
The above is the control of the data, the following is the control of the consumer data.
IF (in == OUT && Buffer [OUT]! = 0) / * Judging whether IN is pointing to a zone, and is not empty, then the OUT pointer does not move * /
Buffer [OUT] = 0;
ELSE / * Otherwise, the OUT pointer is moved backward * /
{
Buffer [OUT] = 0;
OUT = (OUT 1)% buffer_size;
}
For the mutual exclusion of the process, the SMAPHORE can be implemented with SMAPHORE. This program defines a signal light SEM with SEM_T, and uses SEM_POST (& SEM) in production, consumption, when using SEM_WAIT (& SEM), consumption, consumption Can consume.
Fourth, debug report
There is a lot of syntax errors and logical errors during the debugging process. Here I chose some questions and explained.
Using the Random function when using the TurboC2 compiler under Windows, use the Random function to pass directly to the Random in the form of the parameters, such as the random number of 0-9, but if used in Linux, the following error prompt will appear : Course_design.c: in function `produpe ':
Course_design.c: 21: Too Many Arguments to Function `Random '
Therefore, it will be changed to the random number of 1-10 in such a way of random ()% 10 1.
Course_design.c: 13: Parse Error Before "SEM"
Course_design.c: 13: Warning: Data Definition Has No Type or Storage Class
Less header file #include "semaphore.h" course_design.c: in function `Product ':
Course_design.c: 32: Parse Error Before "Pthread_T"
Course_design.c: in function `Consume ':
Course_design.c: 51: Parse Error Before "Pthread_T"
Because the Display function is called in Produce and Consume, this should use Display (ID), but the above error prompt appears because of careless use of Display (PTHREAD_T ID).
Once I have written pThread_t, LPTHREAD, the following prompt error occurred.
Course_design.c: 16: Parse Error Before "ID"
Course_design.c: in function `Product ':
Course_design.c: 32: `ID 'undeclared (First Use in this function)
Course_design.c: 32: (Each undeclared Identifier is Reported Only ONCE
Course_design.c: 32: for Each Function IT APPEARS IN.
Find a lot of time to find out the cause
The above is a number of grammar problems, so it is more convenient to check the error. But more importantly, logical errors, it compiles, can run, but the results have problems. This is often a problem with algorithm.
The problem in this regard appears:
1. Problem of thread mutual exclusion. For example, SEM_POST (& SEM); the location is not put, especially if it is placed outside the while (1) loop, there will be a one-time production. SEM_WAIT (& SEM); also appears similar problems.
Second, the problem occurs in the control of IN and OUT, if it is considered that 10 buffers can only take advantage of 8 or 9 spaces. When the program debugging, I found that the wrong mistake was very naive. In the case of the problem, there was too much, a small mistake or consideration will fail, so now it is not one.
Solve the above problems, the program can basically run correctly, because the starting synchronization effect is not very good, after the teacher's prompt, I finally created 8 threads, later I finally understood The teacher's meaning, the more threads, the more intense the resources of the system, so they will have a good synchronization effect.
V. Output results
Buffer [7] = 2
Buffer [8] = 8
Buffer [9] = 5
IN = 7
OUT = 7
Consume an item: the id of thread is 134519388
Buffer [0] = 1
Buffer [1] = 7
Buffer [8] = 8
Buffer [9] = 5
IN = 7
OUT = 7
Product an item: the id of thread is 134519380
Buffer [0] = 1
Buffer [1] = 7
Buffer [7] = 8
Buffer [8] = 8
Buffer [9] = 5
IN = 7
OUT = 7
Consume an item: the id of thread is 134519384
Buffer [0] = 1
Buffer [1] = 7buffer [8] = 8
Buffer [9] = 5
IN = 7
OUT = 7
Product an item: the id of thread is 134519380
Buffer [0] = 1
Buffer [1] = 7
Buffer [7] = 2
Buffer [8] = 8
Buffer [9] = 5
IN = 7
OUT = 7
Consume an item: the id of thread is 134519468
Buffer [0] = 1
Buffer [1] = 7
Buffer [8] = 8
Buffer [9] = 5
IN = 7
OUT = 7
Product an item: the id of thread is 134519360
Buffer [0] = 1
Buffer [1] = 7
Buffer [7] = 5
Buffer [8] = 8
Buffer [9] = 5
IN = 7
OUT = 7
Consume an item: the id of thread is 134519388
Buffer [0] = 1
Buffer [1] = 7
Buffer [8] = 8
Buffer [9] = 5
IN = 7
OUT = 7
Product an item: the id of thread is 134519360
Buffer [0] = 1
Buffer [1] = 7
Buffer [7] = 2
Buffer [8] = 8
Buffer [9] = 5
IN = 7
OUT = 7
Consume an item: the id of thread is 134519384
Buffer [0] = 1
Buffer [1] = 7
Buffer [8] = 8
Buffer [9] = 5
IN = 7
OUT = 7
Product an item: the id of thread is 134519360
Buffer [0] = 1
Buffer [1] = 7
Buffer [7] = 8
Buffer [8] = 8
Buffer [9] = 5
IN = 7
OUT = 7
Consume an item: the id of thread is 134519392
Buffer [0] = 1
Buffer [1] = 7
Buffer [8] = 8
Buffer [9] = 5
IN = 7
OUT = 7
[lc @ hawk course_design] $
Six, source code
/ * This experiment is implemented, and two threads, one producer thread, a consumption thread * /
#include "stdlib.h"
#include "pthread.h"
#include "semaphore.h"
#include "time.h"
#define buffer_size 10
INT buffer [buffer_size]; / * buffer * /
INT IN = 0; / * Enter a pointer to point to the last inserted data * /
INT out = 0; / * Output pointer, pointing to the first inserted data * /
PTHREAD_T T1, T2, T3, T4, T5, T6, T7, T8;
SEM_T SEM; / * Signal Light * /
Void Product (PTHREAD_T ID) / * Producer Function, this program directly implements complete use of buffer through the loop queue * /
{
INT nextProduces; / * Temporary variables for inserted data * /
While (1) {
NextProducesD = random ()% 10 1; / * In order to generate a random number of 1-10, pass the method 10 method * /
While ((in 1)% buffer_size) == out) / * Judgment if there is inserted space * /
;
Printf ("/ NProduce An Item:");
IF (in == OUT && Buffer [in] == 0) / * Judgment is a buffer data, at which time IN pointer does not move backward * /
Buffer [in] = NextProduces;
Else / * Otherwise, the IN pointer is moved backward * /
{
Buffer [(in 1)% buffer_size] = nextProduces;
IN = (in 1)% buffer_size;
}
Display (ID); / * Call the status function of the display buffer * /
SEM_POST (& SEM); / * Add a resource * /
}
}
Void Consume (PTHREAD_T ID)
{
While (1)
{
SEM_WAIT (& SEM); / * Reduce a resource * /
Printf ("/ nconsume an item:"); / * Display the ID number of the thread * /
IF (in == OUT && Buffer [OUT]! = 0) / * Judging whether IN is pointing to a zone, and is not empty, then the OUT pointer does not move * /
Buffer [OUT] = 0;
ELSE / * Otherwise, the OUT pointer is moved backward * /
{
Buffer [OUT] = 0;
OUT = (OUT 1)% buffer_size;
}
Display (ID);
}
}
INT Display (pthread_t id)
{
INT I;
Printf ("THE ID of Thread IS% D", ID);
For (i = 0; i <10; i )
{
IF (Buffer [I]! = 0) / * This program determines whether or not there is data * /
Printf ("/ nbuffer [% d] =% d", i, buffer [i]);
}
Printf ("/ nin =% d", in);
Printf ("/ Nout =% D", OUT;
}
Int main (void)
{
SEM_INIT (& SEM, 0, 0); / * Initialization Signal Data * /
PTHREAD_CREATE (& T1, NULL, (VOID *) Product, & T1); / * Create a producer thread * /
Pthread_create (& T2, NULL, (VOID *) Consume, & T2); / * Create a consumer thread * /
PThread_create (& T3, NULL, (VOID *) Product, & T3); / * Create a producer thread * /
Pthread_create (& T4, NULL, (VOID *) Consume, & T4); / * Create a consumer thread * /
Pthread_create (& T5, NULL, (VOID *) Product, & T5); / * Create a producer thread * /
Pthread_create (& T6, NULL, (VOID *) Consume, & T6); / * Create a consumer thread * /
PThread_create (& T7, NULL, (VOID *) Product, & T7); / * Create a producer thread * /
Pthread_create (& T8, NULL, (VOID *) Consume, & T8); / * Create a consumer thread * / pthread_join (t1, null); / * Prevent procedures from exapplying * /
}
Seven, summary
I have learned a lot of knowledge through the preparation, design, debugging and operation of this program. First, I have deepened that I understand the thread and process, eliminating the mystery of multi-threaded software design. There is a lot of obstacles in the preparation and design phase, which may be less procedures for the system level. In addition to the teacher's programming information about the Linux multi-threaded program, I also searched a lot of information online, but in the end 4.4 The signal light is implemented. For the complete utilization of the buffer, I tested my understanding of the data structure. Here I used the idea of cyclic queue. More importantly, the problem is to appear in the debug phase. The debug report above the fourth point is just one of them, and the basic skills of my C language are fully tested. The most exciting thing is to successfully run in my own with my classmates, although the effect is not expected.