Looked at Apue's chapter15, only focused on 15.10, learned the POSIX semaphore. The POSIX semaphore has the advantage of better performance than the XSI signal, and the performance on the Linux3.2.0 platform is greatly improved. Where the named semaphore is used in the following way.
1. header file # include <semaphore.h>
2. Function:
(1) sem_t* sem_open (const char * name,int Oflag, mode_t mode, unsigned int value)
This function is to create the semaphore before use, name is the string name you want to create this named semaphore. Name must begin with/, and no longer be allowed at the back.
Oflag generally have two kinds of values, o-creat and o-creat| O-excl. When the value is o-creat, you need to provide values for all four parameters. If the semaphore does not exist, a new one is created, if present, is used, and no initialization occurs. Value is o-creat| At o-excl time, you also need to provide values for all four parameters, and if the semaphore already exists, Sem_open will go wrong.
The value of mode is similar to the permission code for a Linux file. User reads (4), user write (2), user Execution (1), group read (4), group write (2), group Execution (1), other read (4), other write (2), other execution (1). For example, the online code of the mode to take 0644, indicating that the current user has read and write permissions, group users and other users only Read permissions. (Linux file permissions modification is chmod 740 file name, the number before the 0, unlike here.) It may be that the command automatically operates on the back of 740 as a 8-digit binary. C programming says that starting with 0 is the 8 binary number. The Web page says: mode_t is an unsigned int type. Reference pages----the mkdir () function, mode_t parameter, and the mode in mkdir and chmod have similar usage.
If you use only the value of a named semaphore that already exists, you can do so as long as the value of the supplied Name,oflag is set to 0.
Value is the initial value of this semaphore, and if it is a two-dollar semaphore, it generally takes 1.
If the function succeeds, it returns a pointer to the sem_t struct, which is the semaphore that was just created. Returns sem_failed when an error occurs.
This sem_t structure created by Sem_open may have been opened in the kernel. Online says: The known semaphore is persistent with the kernel, so if we don't call Sem_unlink to delete it, it will persist until the kernel restarts (if a process creates a known semaphore and exits, the semaphore still exists). Online said: Famous sem_t is put in the file, nameless sem_t is put in memory.
(2) int sem_wait (sem_t* sem)
After creating the semaphore, if you want to acquire a lock, use sem_wait, if the semaphore is at 0, this wait causes the current wait thread to hibernate until the value of the semaphore is 1, and the current thread can be awakened, acquiring a lock, and performing a semaphore value minus 1 action.
(3) int sem_post (sem_t* sem)
Sem_post is the act of releasing a lock, which increases the value of the semaphore by 1, releasing the lock acquired by the current thread.
(4) int sem_close (sem_t* sem)
If you do not use semaphores, you need to turn them off, possibly freeing up the memory created by creating semaphores. The function parameter is a pointer to the sem_t type.
(5) int sem_unlink (char* name)
This function is used to destroy a named semaphore from the kernel. Executes after the Sem_close executes.
(2) (3) (4) (5) function if execution fails, what value will be returned, not yet known.
Here are some test code:
GCC Main.c-o main-lpthread
Note: When you copy from Word to txt text, the double quotation marks are in the wrong format and need to be modified to double quotation marks in English. Need to include <fcntl.h>, o_creat is defined in this file. Set the sem_t* variable to a global variable that is easy for each thread to use.
The problem with testing: run main for the first time and run well. CTRL + C ends the process, and the second time you run main, a thread deadlock occurs. The reason is that no code sem_unlink has been executed, resulting in the subsequent re-use of the original named semaphore, but it was locked by the previous process at 0. After the process wants to acquire the lock, it is dead locked. Online information: After the process is finished, the kernel does not unlock the locks acquired by the process. Reboot the system (kernel), the semaphore disappears and can be used again.
Workaround: Change the infinite loop of the child thread to 50 cycles, thus executing the exit code for the bus path: Sem_close and Sem_unlink, ensuring that the semaphore is destroyed before exiting. At the same time after each thread releases the lock, the empty Loop 10,000 times (10,000 times to achieve good results, 5000 is not insured), so that another thread has enough time to be awakened, compete to lock, Not a thread will always get to the lock (this is the interview of the Nanjing asked me the topic: multithreaded programming has not encountered a thread running fast enough to repeatedly acquire locks. I came back to the test and found that this was true.
The modified code is placed behind.
Main.c
#include <semaphore.h>
#include <pthread.h>
#include <stdio.h>
#include <fcntl.h>//o_creat
sem_t* sem1;
sem_t* sem2;
void* thfunc1 (void* Arg)
{
for (;;)
{
Sem_wait (SEM1);
printf ("This is Thread1 printing!\n");
Sem_post (SEM1);
}
Return ((void*) 0);
}
void* Thfunc2 (void* Arg)
{
for (;;)
{
Sem_wait (SEM1);
printf ("This is Thread2 printing!\n");
Sem_post (SEM1);
}
Return ((void*) 0);
}
int main (int argc,char* argv[])
{
Const char* C1 = "/wang_sem1";
int res;
pthread_t Tid1,tid2;
void* C;
Sem1 = Sem_open (c1,o_creat,0644,1);
res = pthread_create (&tid1,null,thfunc1,null);
if (res!=0) {
printf ("Can ' t creat thread:%s\n", Strerror (res));
}
res = pthread_create (&tid2,null,thfunc2,null);
if (res!=0) {
printf ("Can ' t creat thread:%s\n", Strerror (res));
}
Pthread_join (TID1,&C);
Pthread_join (TID2,&C);
Sem_close (SEM1);
res = Sem_unlink (c1);
if (res!=0)
printf ("Can ' t delete semaphore\n");
return (0);
}
Modified MAIN.C
#include <semaphore.h>
#include <pthread.h>
#include <stdio.h>
#include <fcntl.h>//o_creat
sem_t* sem1;
sem_t* sem2;
void* thfunc1 (void* Arg)
{
int i,j;
for (i=0;i<50;i++)//for (;;)
{
Sem_wait (SEM1);
printf ("This is Thread1 printing!\n");
Sem_post (SEM1);
for (j=0;j<10000;j++)
{
}
}
Return ((void*) 0);
}
void* Thfunc2 (void* Arg)
{
int i,j;
for (i=0;i<50;i++)//for (;;)
{
Sem_wait (SEM1);
printf ("This is Thread2 printing!\n");
Sem_post (SEM1);
for (j=0;j<10000;j++)
{
}
}
Return ((void*) 0);
}
int main (int argc,char* argv[])
{
Const char* C1 = "/wang_sem1";
int res;
pthread_t Tid1,tid2;
void* C;
Sem1 = Sem_open (c1,o_creat,0644,1);
res = pthread_create (&tid1,null,thfunc1,null);
if (res!=0) {
printf ("Can ' t creat thread:%s\n", Strerror (res));
}
res = pthread_create (&tid2,null,thfunc2,null);
if (res!=0) {
printf ("Can ' t creat thread:%s\n", Strerror (res));
}
Pthread_join (TID1,&C);
Pthread_join (TID2,&C);
Sem_close (SEM1);
res = Sem_unlink (c1);
if (res!=0)
printf ("Can ' t delete semaphore\n");
return (0);
}
apue3rd_chapter15.10 POSIX semaphore for multithreaded programming