Semaphore-Summary of operating system experiments

Source: Internet
Author: User
Semaphore-operating system experiment Summary-general Linux technology-Linux programming and kernel information. The following is a detailed description. This semaphore experiment has plagued me for several days. LINUX has always encountered errors when it is well tuned in WINDOWS. I finally finished it tonight. I would like to sum up the following lessons:

In LINUX, The semaphores control thread synchronization problem. C language:

Key content used:

1) Data Structure of P and V Operations: struct sembuf P, V;

2) parameter data structure union semun arg that assigns initial values to semaphores;

3) semaphore ID: int semid;

4) applied semaphore: semid = semget (IPC_PRIVATE, 1, IPC_0666 | IPC_CREAT );

(The first parameter is a key value generated by the system. You can also use a specific integer value as the key value. The latter parameter is applicable to any process without a family relationship, they need to specify the external identifier of the semaphores to be shared in advance. if IPC_PRIVATE is used in a non-parent-child process, different semaphores are corresponding to different semaphores because of the key values, but not the semaphores corresponding to a key.

The second parameter identifies the number of semaphores in the semaphores set;

The third parameter indicates the operation permission. 0666 indicates that any user can read and write data. If only the IPC_CREAT bit of semflg is set, a semaphore set is created. If the semaphore set already exists, its identifier is returned)

5) Assign the initial value arg. val = the initial value to the semaphore.

Semctl (semid, 0, SETVAL, arg );

6) PV operations for defining semaphores:

P. sem_num = 0;
P. sem_op =-1; // indicates a minus 1 operation.
P. sem_flg = SEM_UNDO;
V. sem_num = 0;
V. sem_op = 1; // Add 1 Operation
V. sem_flg = SEM_UNDO;

7) execute the PV operation on the semaphore:

Semop (semid, & P, 1 );

Semop (semid, & V, 1 );

8) cancelling semaphores

Semctl (semid, IPC_RMID, 0 );

Problems:

1. header file:

Too many header files may cause problems. For example, if both linux/sem. h and sys/sem. h are included, an error is reported, indicating a definition conflict.

2. pthread-related functions are not recognized:

Add the parameter-lpthread during compilation.

> Gcc-o main. c-lpthread

>./Main

3. for Loop Error:

Note the differences between C language and C ++. C language does not allow for (int I = 0; I
4. The output result is garbled:

Because I am running in linux, the file to be read is under it. the sxw file may be garbled due to inconsistent encoding. I didn't clear it. what is sxw encoding? I just changed it. c file, read successfully.

5. Only hReader Process execution. The hPrinter process is not executed:

Solution: Add sleep (1) After semop (printid, & V, 1) to wait for a while, and then semop (mutexid, & V, 1)

Otherwise, hReader may be blocked before hPrinter wakes up. hReader first blocks hPrinter.

This is my understanding. Do you remember to remind me ~



Source code:

# Include
# Include
# Include
# Include
# Include
# Include

Int mutexid; // The mutexid of the semaphore.
Int printid; // semaphore ID printid
Int readid; // The readid of the semaphore.
Struct sembuf P; // P operation
Struct sembuf V; // V operation
Union semun arg1; // returns the structure of the initial value to the semaphore.
Union semun arg2; // same as above
Union semun arg3; // same as above
FILE * fp; // FILE pointer

Int TotalWords = 0;
Int TotalOddWords = 0;
Int TotalEvenWords = 0;

Void m_print (void * Arg );
Void m_read (void * Arg );



Int main ()
{
Mutexid = semget (IPC_PRIVATE, 1,0666 | IPC_CREAT); // apply for a semaphore set with only one semaphore
Printid = semget (IPC_PRIVATE, 1,0666 | IPC_CREAT );
Readid = semget (IPC_PRIVATE, 1,0666 | IPC_CREAT );

Arg1.val = 1; // assign an initial value
Arg2.val = 0;
Arg3.val = 1;

Semctl (mutexid, 0, SETVAL, arg1); // associate arg with the semaphore identifier to assign the initial value to the semaphore
Semctl (printid, 0, SETVAL, arg2 );
Semctl (readid, 0, SETVAL, arg3 );

P. sem_num = 0;
P. sem_op =-1; // indicates a minus 1 operation.
P. sem_flg = SEM_UNDO;
V. sem_num = 0;
V. sem_op = 1; // Add 1 Operation
V. sem_flg = SEM_UNDO;

Pthread_t hReader [3]; // declare the thread handle
Pthread_t hPrinter;

If (fp = fopen ("/root/abc. c", "rt") = NULL) // try to open the file
{
Printf ("Cannot open file strike any key exit! ");
Exit (1 );
}

Int I; // note: the C language and C ++ are different. The C language cannot declare the int I = 0 variable in the for loop;
Int j;
Pthread_create (& hPrinter, NULL, (void *) m_print, NULL); // create a thread. Note the parameter writing method.
For (I = 0; I <3; I ++)
{
Pthread_create (& hReader , NULL, (void *) m_read, NULL );
}
For (j = 0; j <3; j ++)
{
Pthread_join (hReader [j], NULL); // The main thread waits until the subthread ends.
}
Pthread_join (hPrinter, NULL );
Semctl (mutexid, IPC_RMID, 0); // cancel the semaphore
Semctl (readid, IPC_RMID, 0 );
Semctl (printid, IPC_RMID, 0 );

Return 0;

}


Void m_print (void * Arg)
{
While (1)
{
Semop (printdid, & P, 1); // execute the P operation on the semaphore printid
Printf ("This line has des ");
Printf ("% d", TotalWords );
Printf ("words ");
Printf ("% d", TotalEvenWords );
Printf ("even words ");
Printf ("% d", TotalOddWords );
Printf ("odd words ");

TotalWords = 0;
TotalEvenWords = 0;
TotalOddWords = 0;
Semop (readid, & V, 1); // perform the V Operation on the semaphore readid
}
}


Void m_read (void * Arg)
{
While (1)
{
Semop (readid, & P, 1); // perform the P operation on the semaphore readid
Semop (mutexid, & P, 1); // perform the P operation on the semaphore mutexid
Char ch;
Int count = 0;
Ch = fgetc (fp); // read the content of the file pointed to by fp, And put
If (ch = EOF)
{
Break;
}
While (ch! = '\ N ')
{
If (ch = '')
{
If (count % 2 = 0)
{
TotalEvenWords ++;
}
Else
{
TotalOddWords ++;
}
TotalWords ++;
Count = 0;
}
Else
{
Count ++;
}
Putchar (ch); // output the content in ch to the screen
Ch = fgetc (fp );
}
If (count % 2 = 0)
{
TotalEvenWords ++;
}
Else
{
TotalOddWords ++;
}
TotalWords ++;
Putchar ('\ n ');
Semop (printid, & V, 1); // perform the V Operation on the semaphore printid
Sleep (1); // wait for a while
Semop (mutexid, & V, 1); // perform the V Operation on the semaphore mutexid
}

}


Using semaphores in Windows, C ++:

Key APIs:

1) WaitForSingleObject (p, WaitTime) is equivalent to wait (p );

2) ReleaseSemaphore (s, 1, NULL); equivalent to signal (s );

3) semaphore handle declaration:

HANDLE mutex;
HANDLE p; // print
HANDLE s; // statistics

4) create a semaphore:

Mutex = CreateSemaphore (NULL, 1, 1, NULL );
P = CreateSemaphore (NULL, 0, 1, NULL );
S = CreateSemaphore (NULL, 1, 1, NULL );

The second parameter is the initial value.

5) Declare the thread handle:

HANDLE thHd;

6) Creation thread:

ThHd = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) & print, & Printer, 0, & Printer. thId );

Problems:

1) file read/write:

Determine if bool infile. eof () is used at the end ()

2) The main thread waits for the sub-thread:

I didn't find the API, so I had to use while (1) {} to wait forever... failed ..

Source code: (write more)

# Include
# Include
Using std: cout;
Using std: endl;
Using std: ios;

# Include
Using std: fstream;
Using std: ifstream;
Using std: ofstream;

Struct Thread
{
HANDLE thHd;
DWORD thId;
Int index;
} Reader [3];

Thread Printer;
Bool over = false;

HANDLE mutex;
HANDLE p; // print
HANDLE s; // statistics
DWORD WaitTime = 2000;
Ifstream infile;
Int TotalWords = 0;
Int TotalOddWords = 0;
Int TotalEvenWords = 0;

Void print (Thread printer)
{
While (true)
{
If (WaitForSingleObject (p, WaitTime) = WAIT_OBJECT_0)
{
Cout <"This line has des" < < < TotalWords = 0;
TotalOddWords = 0;
TotalEvenWords = 0;
ReleaseSemaphore (s, 1, NULL );
}
}
}

Void read (Thread * th)
{

While (! Over)
{
If (WaitForSingleObject (s, WaitTime) = WAIT_OBJECT_0)
{
If (WaitForSingleObject (mutex, WaitTime) = WAIT_OBJECT_0)
{
// Cout <"Thread" < Index <
Char ch;
Int count = 0;
Infile. get (ch );
If (infile. eof ())
{
Over = true;
}
Else
{

While (ch! = '\ N ')
{
If (ch = '')
{
If (count % 2 = 0)
{
TotalEvenWords ++;
}
Else
{
TotalOddWords ++;
}
TotalWords ++;
Count = 0;
}
Else
{
Count ++;
}
Cout < Infile. get (ch );
If (infile. eof ())
{
Count --;
Break;
}

}
Count ++;
If (count % 2 = 0)
{
TotalEvenWords ++;
}
Else
{
TotalOddWords ++;
}

TotalWords ++;
Cout <'\ n ';
ReleaseSemaphore (p, 1, NULL );
ReleaseSemaphore (mutex, 1, NULL );
}

}
}
}
}

Int main ()
{
Mutex = CreateSemaphore (NULL, 1, 1, NULL );
P = CreateSemaphore (NULL, 0, 1, NULL );
S = CreateSemaphore (NULL, 1, 1, NULL );
Const char * file = "F: \ myFile.txt ";
Infile. open (file, ios: binary );
If (! Infile)
{
Cout <"error !! "< Return 0;
}
For (int I = 0; I <3; I ++)
{
Reader . Index = I;
Reader. ThHd = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) & read, & Reader, 0, & Reader. ThId );
}
Printer. index = 0;
Printer. thHd = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) & print, & Printer, 0, & Printer. thId );
// Infile. close ();
While (1)
{}
Return 0;
}
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.