


How to implement Linux multi-thread programming
Introduction
Conditional variables are a mechanism that uses global variables shared between threads for synchronization. It mainly includes two actions: one thread waits for the condition of the condition variable to be established and hangs (it no longer occupies the CPU at this time); Another thread makes the condition true (gives a signal that the condition is true). To prevent contention, the use of condition variables is always combined with a mutex lock.
Function prototype
1. Define condition variables
#include <pthread.h> /* 定义两个条件变量 */ pthread_cond_t cond_pro, cond_con;
2. Initialize and destroy condition variables
#include <pthread.h> int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);int pthread_cond_destroy(pthread_cond_t *cond); /* 初始化条件变量 */ pthread_cond_init(&cond_pro, null); pthread_cond_init(&cond_con, null); /* 销毁条件变量 */ pthread_cond_destroy(&cond_pro); pthread_cond_destroy(&cond_pro);
3. Wait and fire conditions
#include <pthread.h> int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex); int pthread_cond_broadcast(pthread_cond_t *cond); int pthread_cond_signal(pthread_cond_t *cond); /* 等待条件 */ /* 注意:pthread_cond_wait为阻塞函数。解开锁,再等待。等条件满足时,需要抢到锁,才可以被唤醒*/ pthread_cond_wait(&cond_pro,&mutex); /* 激发条件 */ /* 所有因为不满足条件的线程都会阻塞在条件变量cond_pro中的一个队列中 */ /* 以广播方式,通知所有被阻塞的所有线程 */ pthread_cond_broadcast(&cond_pro); /* 以signal方式,只通知排在最前面的线程 */ pthread_cond_signal(&cond_pro);
Code
/************************************************************************* > file name: my_con.c > author: krischou > mail:zhoujx0219@163.com > created time: tue 26 aug 2014 10:24:29 am cst ************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <pthread.h> #include <unistd.h> #define cell 10 #define flore 0 int i = 0; /* 所有线程共享的全局变量,此处假定至多递增至10,最小减到0 */ pthread_mutex_t mutex; /* 定义互斥锁 */ pthread_cond_t cond_pro, cond_con; /* 定义两个条件变量 */ /* 生产者线程 */ void* pro_handler(void *arg) { pthread_detach(pthread_self()); /* 由系统回收线程资源,而非主线程回收资源 ,此类情况主线程是个服务器,永久不会退出 */ while(1) { pthread_mutex_lock(&mutex); while(i >= cell) { pthread_cond_wait(&cond_pro,&mutex); /* continue是轮询,此处是阻塞 */ /* 把锁放开再等 ,第一个参数是结构体指针,其中有成员存放被阻塞的函数 */ /*不占cpu*/ /* 不满足条件时才会等 ,需要别人告诉它,才能唤醒它*//* 当它返回时,锁也要回来了*/ } i++; if(i == 1) { /* 由空到不空,唤醒消费者 */ pthread_cond_signal(&cond_con); /*不会立马signal被阻塞的消费者线程,因为其还要等锁抢回来*/ } printf("add i: %d \n", i); pthread_mutex_unlock(&mutex); sleep(rand() % 5 + 1); } } /* 消费者线程 */ void* con_handler(void *arg) { pthread_detach(pthread_self()); while(1) { pthread_mutex_lock(&mutex); while(i <= flore) { pthread_cond_wait(&cond_cno,&mutex); } i--; if(i == 9) /* 由满到不满,要告诉生产者,以便将其唤醒 *//*此处,直接signal也可以,我们是为了更加精确*/ { pthread_cond_signal(&cond_pro); } printf("con i: %d \n", i); pthread_mutex_unlock(&mutex); sleep(rand() % 5 + 1); } } int main(int argc, char *argv[]) // exe +num -num { srand(getpid()); int con_cnt, pro_cnt; pro_cnt = atoi(argv[1]); con_cnt = atoi(argv[2]); pthread_mutex_init(&mutex,null); pthread_cond_init(&cond_pro,null); pthread_cond_init(&cond_con,null); pthread_t *arr = (pthread_t*)calloc(con_cnt + pro_cnt , sizeof(pthread_t)); int index = 0; while(pro_cnt > 0) { pthread_create(arr + index, null, pro_handler, null); index++; pro_cnt--; } while(con_cnt > 0) { pthread_create(arr + index, null, con_handler, null); index++; con_cnt--; } while(1); pthread_mutex_destroy(&mutex); pthread_cond_destroy(&cond_pro); pthread_cond_destroy(&cond_con); return 0; }
Note
Whether it is in the producer thread or the consumer thread. The judgment condition marked in yellow must use while. Taking the producer thread as an example, when i>=cell, that is, when i is full, pthread_cond_wait(&cond_cno,&mutex); is executed at this time and the producer thread is suspended. Must wait until the consumer thread pthread_cond_signal(&cond_pro); wakes it up. But it is not enough for the consumer to signal it. The producer thread that is suspended must get the lock again before it can be activated. However, since the producer cannot immediately grab the lock when the consumer signals, the i value may change to greater than or equal to 10 at this time. Therefore you must use while. Otherwise, i>10 may result.
The above is the detailed content of How to implement Linux multi-thread programming. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics











The five basic components of the Linux system are: 1. Kernel, 2. System library, 3. System utilities, 4. Graphical user interface, 5. Applications. The kernel manages hardware resources, the system library provides precompiled functions, system utilities are used for system management, the GUI provides visual interaction, and applications use these components to implement functions.

VS Code One-step/Next step shortcut key usage: One-step (backward): Windows/Linux: Ctrl ←; macOS: Cmd ←Next step (forward): Windows/Linux: Ctrl →; macOS: Cmd →

To view the Git repository address, perform the following steps: 1. Open the command line and navigate to the repository directory; 2. Run the "git remote -v" command; 3. View the repository name in the output and its corresponding address.

Although Notepad cannot run Java code directly, it can be achieved by using other tools: using the command line compiler (javac) to generate a bytecode file (filename.class). Use the Java interpreter (java) to interpret bytecode, execute the code, and output the result.

There are six ways to run code in Sublime: through hotkeys, menus, build systems, command lines, set default build systems, and custom build commands, and run individual files/projects by right-clicking on projects/files. The build system availability depends on the installation of Sublime Text.

The main uses of Linux include: 1. Server operating system, 2. Embedded system, 3. Desktop operating system, 4. Development and testing environment. Linux excels in these areas, providing stability, security and efficient development tools.

To install Laravel, follow these steps in sequence: Install Composer (for macOS/Linux and Windows) Install Laravel Installer Create a new project Start Service Access Application (URL: http://127.0.0.1:8000) Set up the database connection (if required)

Installing Git software includes the following steps: Download the installation package and run the installation package to verify the installation configuration Git installation Git Bash (Windows only)
