Semaphore communication-an example of extracting and modifying the Internet

Source: Internet
Author: User

# Include <stdio. h>
# Include <sys/types. h>
# Include <sys/ipc. h>
# Include <sys/sem. h>
# Include <sys/unistd. h>
# Include <stdlib. h>
# Include <math. h>
# Include <errno. h>

/*************************************** *************
The main function of semaphores is to restrict multi-thread or process access to critical zones, similar to mutex.
Example: If there are only N ticket receiving channels, you can only allow N users to get tickets at the same time,
In this case, if M is personal and M> N is needed, the channel that cannot be accessed can use the blocking wait and non-blocking wait
**************************************** **************/

Int main (){
Int pid; // process ID
Int val = 1; // number of available resources, that is, number of channels N = 1
Int semid; // It is the identification code of the semaphore set.

Key_t semkey; // unique key value

If (semkey = ftok ("/tmp", 0) <0) // convert the file path and Project ID ("1" later) to System v ipc key
{
Printf ("ftok Function Conversion error. \ N ");
Exit (1 );
} Else
Printf ("ftok Function Conversion successful, key value: % d \ n", semkey );

If (Semid = semget (semkey, 1, ipc_creat | ipc_excl | 0700) <0) // create a traffic signal set, which contains one traffic signal.
{
Printf ("an error occurs when the semget function creates a traffic signal set. \ N ");
Exit (2 );
} Else
Printf ("semget function successfully created the signal set, signal set identification code Semid: % d \ n", Semid );

If (semctl (semid, 0, SETVAL, val) <0) // This sentence is used together with the previous sentence to set the number of available resources for the first signal (0 indicates the first signal) in the semid signal set to 1.
{
Printf ("The semctl function fails to set the number of available resources. \ N ");
Exit (9 );
} Else
Printf ("The semctl function sets the number of available resources. \ N ");

If (pid = fork () <0 ){
Printf ("an error occurs when the fork function creates a sub-process. \ N ");
Exit (3 );
} Else if (pid> 0) // parent process, obtain shared resources, and then release
{
Struct sembuf p_op_buf, v_op_buf;
Printf ("parent process ID: % d, this process will ask for shared resources \ n", getpid ());
P_op_buf.sem_num = 0;
P_op_buf.sem_op =-1; // The requested resource is-1, so that the outbound resource is + 1
If (semop (semid, & p_op_buf, 1) <0) // the preceding three rows apply for a resource from the first traffic signal of the semid signal set.
{
Printf ("an error occurs when the semop function requests shared resources in the parent process. \ N ");
Exit (4 );
} Else {
Int I;
Printf ("in the parent process, the semop function successfully requests shared resources. The number of requests is % d \ n", abs (p_op_buf.sem_op ));
Printf ("the parent process with ID % d needs to sleep for 6 seconds now. \ N ", getpid ());
For (I = 6; I> 0; I --){
Printf ("% d process (parent process) sleeps % d seconds ...... \ N ", getpid (), I );
Sleep (1 );
}
Printf ("% d process (parent process) has woken up and resources will be released. \ N ", getpid ());
V_op_buf.sem_num = 0;
V_op_buf.sem_op = 1;
P_op_buf.sem_flg = 0; // if this flag is not cleared, no error will occur. However, the flag in the process should be cleared because the parent process occupies resources, if the sub-process fails to apply for resources, the flag is not cleared (for example, if no value is assigned by default), an error may occur.
If (semop (Semid, & v_op_buf, 1) <0) // the preceding three rows release a resource to the first signal lamp set represented by Semid.
{
Printf ("an error occurs when the semop function requests shared resources in the parent process. \ N ");
Exit (5 );
} Else {
Printf ("in the parent process with ID % d, the semop function successfully released the shared resource, and the number of released resources is % d \ n", getpid (),
V_op_buf.sem_op );
Sleep (1 );
}
}
} Else // The sub-process keeps applying for shared resources. After applying, declare it and release it.
{
Struct sembuf p_op_buf, v_op_buf;
Sleep (2); // wait for the parent process to occupy unique resources
Printf ("sub-process ID: % d, this process will ask for shared resources \ n", getpid ());
P_op_buf.sem_num = 0;
P_op_buf.sem_op =-1;

// Sem_flg: indicates the signal operation flag. There are two possible options:
// When ipc_nowait cannot meet the signal operation requirements, semop () will not block, return immediately, and set the error message.
// When the sem_undo program ends (whether normal or abnormal), ensure that the signal value is reset to the value before semop () is called. The purpose of this operation is to prevent the program from unlocking the locked resource at the end of an exception, causing the resource to be locked forever.
P_op_buf.sem_flg = sem_undo; // this flag does not need to be cleared. If this flag is not cleared, an error occurs. 0 indicates that the flag is blocked by default.

// Blocking Application
If (semop (Semid, & p_op_buf, 1) <0) // You can request a resource from the first signal lamp of the Semid signal set. If you cannot apply, you will be waiting here, when are resources available and when are the resources going down?
{
Printf ("an error occurred when the semop function requested shared resources in the sub-process: % d \ n", errno );
Exit (6 );
} Else
Printf ("*********** the subroutine has been successfully applied for resources! * ********* \ N ");
V_op_buf.sem_num = 0;
V_op_buf.sem_op = 1;
If (semop (semid, & v_op_buf, 1) <0) // the preceding three rows release a resource to the first signal lamp set represented by semid.
{
Printf ("an error occurs when the semop function requests shared resources in the sub-process. \ N ");
Exit (7 );
} Else {
Printf ("in the sub-process, the semop function has successfully released the shared resource. The number of released resources is % d \ n", v_op_buf.sem_op );
Printf ("process with ID % d (sub-process) exited! \ N ", getpid ());

If (semctl (semid, 0, IPC_RMID, 0) <0 ){
Printf ("An error occurred while calling semctl to delete the semaphore set. \ N ");
Exit (8 );
} Else {
Printf ("the semaphore set with the identification code % d has been deleted \ n", semid );
Exit (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.