System programming day08 signal function (use method of semaphore, function of applying semaphore to initialize semaphore to destroy signal (signal signal capture function)

1. Thread Synchronization - Semaphore

Semaphore is essentially a non negative integer counter, which is usually used to control access to public resources.     

When the available public resources increase, call the function sem_post() increases the semaphore. Only when the semaphore value is greater than 0, the function sem_wait() can be returned, and the semaphore value is reduced by 1. When the semaphore is equal to 0, sem_wait() will be blocked until the semaphore value is greater than 0. Function sem_trywait() is the function sem_ The non blocking version of wait ().

2. Semaphore is the PV primitive used in the operating system. It is widely used for synchronization and mutual exclusion between processes or threads.

Semaphore is essentially a non negative integer counter, which is used to control access to public resources.     

Working principle of PV primitive: PV primitive is an operation on semaphore sem of integer counter. One P operation makes sem minus one, while one V operation makes sem plus one. The process (or thread) determines whether it has access to public resources according to the semaphore value. When the semaphore sem value is greater than or equal to zero, the process (or thread) has access to public resources; On the contrary, when the semaphore sem value is less than zero, the process (or thread) will block until the semaphore sem value is greater than or equal to 0.

3.sem_init is used to create an anonymous semaphore and initialize its value

Header file: # include<semaphore. h>

Prototype: int sem_init(sem_t *sem,int pshared,unsigned int value);

Parameter: sem: semaphore pshared: determines whether semaphores can be shared among several processes. Since Linux has not yet implemented inter process semaphore sharing, this value can only be taken as 0 value: semaphore initialization value

Return value: Success: 0 Error: - 1

4.sem_getvalue -- get the semaphore value

Header file: # include<semaphore. h>

Prototype: int sem_getvalue(sem_t *sem,int * val);

Parameters: sem is the pointer to the semaphore, val is used to store the queried semaphore value

Return value: 0 for success, - 1 for failure

5.sem_destroy -- Clear semaphore

Header file: # include<semaphore. h>

Prototype: int sem_destroy (sem_t * sem);

Parameter: sem is the pointer to the semaphore

Return value: 0 for success, - 1 for failure

6.sem_wait - wait for shared resources (- 1 function)

sem_trywait -- wait for shared resources

Parameter: return value of sem pointer to semaphore: 0 if successful, - 1 otherwise.

Function supplement: sem can be used_ Wait to apply for shared resources, sem_ The wait function can test the value of the specified semaphore. If the value is greater than 0, it is subtracted by 1 and returned immediately. We can use the shared resources applied for. If the value is equal to 0, the calling thread will be put into sleep until the value becomes greater than 0. At this time, reduce it by 1, and the function will return later. sem_ The wait operation must be atomic.

sem_wait and sem_ The difference between trywait: sem_wait and sem_trywait is equivalent to the P operation. Both of them can reduce the semaphore value by one. The difference between the two is that if the semaphore is less than zero,

sem_wait will block the process

And sem_trywait will return immediately

int sem_post(sem_t *sem); (+1 function)

7. Header file: # include<semaphore. h>

Function prototype: int sem_post(sem_t *sem);

Parameter: sem pointer to signal lamp

Return Value: 0 if successful, - 1 otherwise.

Function supplement: when a thread finishes using a semaphore, it should call sem_post to tell the system that the requested resources have been used up. This function and sem_ The wait function has the opposite function. It adds 1 to the value of the specified semaphore, and then wakes up any thread that is waiting for the semaphore value to become a positive number.

89.. Code:

/************************************************************************************************************************************************************************************************************************
 *File name:
 *Author: She001
 *Time:
 *edition:
 *effect:
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore. h> //Functions used by semaphores
// 0. Usage of semaphore
//1. Application semaphore
//2. Initialize semaphore
//3.p Operation - 1 Operation
//4. Read/write operation
//5. v operation+1 operation
//6. Destroy semaphores
//
int main(int argc,char *argv[])
{
	

//1. Application semaphore
	sem_t sem;
//2. Initialize semaphore
	if(sem_init(&sem,0,1)<0)  //Light on
	{
		perror("sem_init  error\n");
		return -1;
	}
	else
	{
		printf("sem_init ok\n");
	}
	//View semaphores
	int value =0;
	sem_getvalue(&sem,&value);
	printf("1 value =  %d\n",value);
	

//3.p Operation - 1 Operation
	sem_wait(&sem); //Light off operation (blocking version)
	sem_getvalue(&sem,&value);
	printf("2 value =  %d\n",value);
	
	int s=sem_post(&sem); //Light on operation
	if(s<0)
	{
		perror("sem_post error\n");
	}
	else
	{
		printf("sem_post ok\n");
	}

	while(sem_trywait(&sem)) //Light on operation of non blocking version
	{
		perror("sem_trywait error\n");
		sleep(1);
	}

//4. Read/write operation
	printf("do something to resourme\n");
//5. v operation+1 operation
	s=sem_post(&sem); //Light on operation
	if(s<0)
	{
		perror("sem_post error\n");
	}
	else
	{
		printf("sem_post ok\n");
	}
	sem_getvalue(&sem,&value);
	printf("3 value =  %d\n",value);
//6. Destroy semaphores
	sem_destroy(&sem);
       return 0;

}

9. Program function: apply the semaphore method to threads

code:

/************************************************************************************************************************************************************************************************************************
 *File name:
 *Author: She001
 *Time:
 *edition:
 *effect:
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore. h> //Functions used by semaphores
// 0. Usage of semaphore
//1. Application semaphore
//2. Initialize semaphore
//3.p Operation - 1 Operation
//4. Read/write operation
//5. v operation+1 operation
//6. Destroy semaphores
//



int num=100;
//1. Application semaphore (global variable)
sem_t sem;
void * pthread_fun1(void *arg)//Function to create thread
{
	while(sem_trywait(&sem)) //Operation of turning off the light without blocking the board
	{
		perror("fun1 sem_trywait error\n");
		sleep(1);
	}

	printf("this is %s %d %ld start \n",__func__,getpid(),pthread_self());
	for(int i=0;i<5;i++)
	{
		num+=1;
		printf("1111111 :%d\n",num);
		sleep(1);
	}
	printf("this is %s %d %ld end \n",__func__,getpid(),pthread_self());
	int s=sem_post(&sem); //Light on operation
	if(s<0)
	{
		perror("sem_post error\n");
	}
	else
	{
		printf("sem_post ok\n");
	}

}

void * pthread_fun2(void *arg)//Function to create thread
{
	while(sem_trywait(&sem)) //Operation of turning off the light without blocking the board
	{
		perror("fun2 sem_trywait error\n");
		sleep(1);
	}
	printf("this is %s %d %ld start \n",__func__,getpid(),pthread_self());
	for(int i=0;i<5;i++)
	{
		num-=2;
		printf("22222222 :%d  \n",num);
		sleep(1);
	}

	printf("this is %s %d %ld end \n",__func__,getpid(),pthread_self());
	int s=sem_post(&sem); //Light on operation
	if(s<0)
	{
		perror("sem_post error\n");
	}
	else
	{
		printf("sem_post ok\n");
	}
}

void * pthread_fun3(void *arg)//Function to create thread
{
	while(sem_trywait(&sem)) //Operation of turning off the light without blocking the board
	{
		perror("fun3 sem_trywait error\n");
		sleep(1);
	}
	printf("this is %s %d %ld start \n",__func__,getpid(),pthread_self());
	for(int i=0;i<5;i++)
	{
		num+=3;
		printf("333333333 :%d\n",num);
		sleep(1);
	}
	printf("this is %s %d %ld end \n",__func__,getpid(),pthread_self());
	int s=sem_post(&sem); //Light on operation
	if(s<0)
	{
		perror("sem_post error\n");
	}
	else
	{
		printf("sem_post ok\n");
	}
}


int main(int argc,char *argv[])
{
	

//2. Initialize semaphore
	if(sem_init(&sem,0,1)<0)  //Light on
	{
		perror("sem_init  error\n");
		return -1;
	}
	else
	{
		printf("sem_init ok\n");
	}
	//View semaphores





	//Create thread
	int value =0;
	sem_getvalue(&sem,&value);
	printf("1 value =  %d\n",value);
	pthread_t tid1 =0;
	pthread_t tid2 =0;
	pthread_t tid3 =0;
	pthread_create(&tid1,NULL,pthread_fun1,NULL);
	pthread_create(&tid2,NULL,pthread_fun2,NULL);
	pthread_create(&tid3,NULL,pthread_fun3,NULL);
	
	
	pthread_join(tid1,NULL); //Do not accept exit status of child thread
	pthread_join(tid2,NULL); //Do not accept exit status of child thread
	pthread_join(tid3,NULL); //Do not accept exit status of child thread

//6. Destroy semaphores
	sem_destroy(&sem);
       return 0;

}

10. Introduction to signal:

1. Signal definition: signal: a method of transmitting messages between processes. The full name of signal is soft interrupt signal, also called soft interrupt. Signals are used to notify the process that an asynchronous event has occurred. There are two sources of signal events: 1. Hardware sources, such as we pressed the keyboard or other hardware failures; 2. Software source. The most commonly used signal related system functions are kill(), raise(), alarm() and setimer (). The software source also includes some illegal operations. Note: The signal is only used to inform a process of what has happened, and does not pass any data to the process.

2 Signal processing by process

A process can respond to and process a signal in three ways: 1. Ignore a signal: ignore a signal and do nothing with it, as if it had never happened. 2 Capture signal: It is a similar interrupt processing program. For the signal to be processed, the process can specify a processing function to be processed by this function// Programming. 3. Execute default operation: the system default value is reserved for the signal processing. The default operation for most signals is to terminate the process

3List of signals supported by Linux

11. Signal transmission and capture

The kill() and raise() kill functions, like the well known kill system commands, can send signals to processes or process groups

alarm() and pause()

The kill – l command is used to view the list of signals supported by the system

The raise function allows a process to send a signal to itself

alarm(), also known as the alarm function, can set a timer in the process. When the timer specified time expires, the kernel sends the SIGALRM signal to the process.

The pause() function is used to suspend the calling process until a signal is received.

 

kill function:

code:

/************************************************************************************************************************************************************************************************************************
 *File name:
 *Author: She001
 *Time:
 *edition:
 *Function: test the kill function
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<signal.h>
int main(int argc,char *argv[])
{
	printf("%s start \n",__func__);
	//kill(getpid(),SIGKILL);
	//kill(getppid(),SIGKILL); // Ctrl+d Close the terminal
	kill(getpid(),SIGTSTP);
	printf("%s end\n",__func__);


       return 0;

}

raise function

alarm function

code:

/************************************************************************************************************************************************************************************************************************
 *File name:
 *Author: She001
 *Time:
 *edition:
 *Functions: other functions of signal
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<signal.h>

//1.raise can only send signals to itself 
//2. After the alarm is called, the kernel sends an alarm signal to the process at the specified time (the operation of the alarm signal is to terminate the task) 
//3.abort//The core dumped functions
//4.pause lets the task calling this function stop until the kernel sends a signal to this task

int main(int argc,char *argv[])
{
	printf("%s  start\n",__func__);
	//raise(SIGKILL);// kill
	//raise(SIGTSTP);// suspend
	//raise(SIGINT);// termination
	
	alarm(5);  //In seconds
	for(int i=1;i<=10;i++)
	{
		printf("this is  alarm sig!\n");
		sleep(1);
		if(i==2)
		{
			//abort();
			pause();
		}

	}


	printf("%s   end\n",__FILE__);//File name
	


       return 0;

}

12. Signal processing

A specific signal is a process associated with a corresponding event. You can set the corresponding mode for the signal

There are two main methods of signal processing: using simple signal() function

When signal() uses the signal function to process, it is necessary to specify the signal to be processed and the processing function. It is simple to use and easy to understand

code:

/************************************************************************************************************************************************************************************************************************
 *File name:
 *Author: She001
 *Time:
 *edition:
 *Function: use of signal function
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<signal.h>
//1.signal    
//2. Task A sends signals to Task B. Task B has three responses 1. Ignore 2. Capture 3. Default
//
//

void sigfun(int signo)
{
	if(signo ==SIGINT )
	{
		printf("file is ctrl + c\n");
	}
	else if(signo == SIGQUIT)
	{
		printf("file is ctrl + \\ \n");
	}
	else if(signo ==SIGTSTP)
	{
		printf("file is ctrl + z  \n");
	}
	else if(signo=SIGALRM)
	{
		printf("alarm signal is  buhuo1\n");
	}
}


int main(int argc,char *argv[])
{
	printf("this is signal test start\n");
	signal(SIGINT,sigfun);
	signal(SIGQUIT,sigfun);
	signal(SIGTSTP,sigfun);
	signal(SIGALRM,sigfun);
	int num =20;
	alarm(5);
	//Restore the original function signal of the signal(SIGINT, SIG_DFL)
	//Ignore the signal function singal (SIGNANT, SIG_IGN);

	//It can capture the termination signal of the alarm function;
	while(num--)
	{
		printf("test num =%d\n",num);
		sleep(1);
	}
	printf("this is singal end \n");

       return 0;

}

Tags: Linux C

Posted by cyberdesi on Thu, 15 Sep 2022 01:53:45 +0930