linux applications: multithreaded programming

Thread is very commonly used in linux application development, because some functions need real-time response, while some functions are time-consuming. Therefore, the concept of concurrency is introduced, that is, task scheduling and time slice rotation. There is only one purpose: to make more efficient use of cpu. So if you don't use other threads, is there any other alternative to threads, such as processes, such as timers? It's OK in terms of function, but strictly speaking, nothing can replace multithreading.

1, Comparison between thread and process:

1. Thread is the most basic running unit of a program and the basic unit participating in system scheduling, and the process cannot run directly

2. The overhead of inter thread switching is less than that of inter process switching, and the creation speed is much faster than that of process creation

3. The system must allocate independent address space for the process and establish many data tables to maintain its code segments, stack segments and data segments

4. Threads use the same address space with each other and share most of the data. Therefore, multiple threads support a variety of communication and interaction modes

5. Processes are equivalent to different applications. It is estimated that socket s can only be used for communication

In short, threads are included in the process, which is the basic unit involved in system scheduling, and the process is equivalent to a container. If there is an application, there must be a process, and a process contains at least one thread. Well, that's it.

2, Thread and software timer comparison

1. Timers are processed periodically, while threads are scheduled based on the system (equivalent to being supervised by a third party)

2. The timer is actually polling the messages in the message queue and then polling for processing. There is no way to deal with time-consuming problems

3. The threads that can be processed by the timer can basically be processed, while the timers that can be processed by the thread may not be processed

According to the above, some people may ask whether the software timer has no value. No, no, the software timer is simple and easy to use, especially to deal with some periodic tasks related to time, and the problems encountered by threads are more difficult to troubleshoot, such as cpu resource preemption, deadlock prone, uncontrollable time slice, etc.

3, Multithreaded programming

Just say not practice fake skills, I still like to go directly to the code and practice in the code

The following two points should be noted:

① . you need to include < pthread h> Header file, which contains API s related to thread operation

② . the - lpthread parameter needs to be added during compilation. Use the - l option to specify the link library pthread. Because pthread is not in the default link library of gcc, it needs to be specified manually.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>

pthread_t tid;
pthread_attr_t attr;
	
static void *hello_thread(void *arg)
{
	//while(1)
	{	//Print current thread id
		printf("hello thread! Id:%ld\n", pthread_self());
		
		printf("arg:%d\n", *(int*)arg);
		
		sleep(1);//The current thread is suspended for 1s
	}
	 return (void *)0; 
}
 
int main(int argc, char *argv[])
{
	int ret;
	size_t stacksize;
	
	/* Initialize the attr object */
	pthread_attr_init(&attr);
	/* The default stack size is 8388608 byte s */
	ret =  pthread_attr_getstacksize(&attr, &stacksize);
	if(ret != 0){
		fprintf(stderr, "pthread_attr_getstacksize failed: %s\n", strerror(ret));
		exit(-1);
	}
	printf("init stacksize = %d\n", stacksize);

	/* Set the stack size to 4K, with a minimum of 16384 byte s */
	ret =  pthread_attr_setstacksize(&attr, 2 * 8 * 1024);
	if(ret != 0){
		fprintf(stderr, "pthread_attr_setstacksize failed: %s\n", strerror(ret));
		exit(-1);
	}
	/* Get stack size */
	ret =  pthread_attr_getstacksize(&attr, &stacksize);
	if(ret != 0){
		fprintf(stderr, "pthread_attr_getstacksize failed: %s\n", strerror(ret));
		exit(-1);
	}
	printf("stacksize = %d\n", stacksize);
	
	/* Create a new thread */
	int arg = 123;//arg parameter, i.e. hello_ Entry parameter of thread function
	ret = pthread_create(&tid, &attr, hello_thread, &arg);
	if (ret) {
		fprintf(stderr, "pthread_create error: %s\n", strerror(ret));
		exit(-1);
	}
	/* Get the current thread, that is, the main thread id and sub thread id */
	printf("main thread id:%ld, sub thread id:%ld\n", pthread_self(), tid);
	
	/* Wait for the new thread to terminate */
	ret = pthread_join(tid, NULL);
	if (ret) {
		fprintf(stderr, "pthread_join error: %s\n", strerror(ret));
		exit(-1);
	}
	/* Destroy attr object */
	pthread_attr_destroy(&attr);
	printf("all thread exit!\n");
	exit(0);
}


Makefile file:

CC=g++
CFLAGS=-Wall -g -pthread -DDEBUG
LDFLAGS=
LIBS=
NAME=test

all: test

test: *.cpp
	$(CC) -o $@ $(CFLAGS) $^ $(LIBS)

clean:
	rm -rf *.o $(NAME)

The operation is as follows:

Keywords: C++

Added by petersro on Mon, 10 Jan 2022 17:49:46 +0200