简体   繁体   English

关键部分取消点

[英]Cancellation points in Critical Section

I have implemented a multithreaded application using pthread.我已经使用 pthread 实现了一个多线程应用程序。 In this application there are two threads:在这个应用程序中有两个线程:

  • The first polls a tap port in order to read the available data and write it to a serial port to which a radio is connected.第一个轮询分接端口以读取可用数据并将其写入与无线电连接的串行端口。
  • The second vice versa polls the serial port and then writes the data to the tap port.第二个反之亦然轮询串行端口,然后将数据写入分接端口。

To avoid data race problems before accessing a port (serial or tap) I use a pthread_mutex_t .为了避免在访问端口(串行或分接)之前出现数据竞争问题,我使用了pthread_mutex_t On https://man7.org/linux/man-pages/man7/pthreads.7.html I read that read() and write() are cancellation points, that is, they are points where a thread can potentially be canceled.https://man7.org/linux/man-pages/man7/pthreads.7.html我读到read()write()是取消点,也就是说,它们是线程可能被取消的点。

Pseudo-Code Example:伪代码示例:

pthread_mutex_t serial_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t tap_mutex = PTHREAD_MUTEX_INITIALIZER;
atomic_bool continue = true;
//T1
void* run(void* vargp)
{
    int poll_timeout = 1000;
    while (continue)
    {
        int poll_result = poll(&tap_fd, 1, poll_timeout);
        if (poll_result != -1 && poll_result != 0)
        {
            if (tap_fd.revents & POLLIN)
            {
                pthread_mutex_lock(&tap_mutex);
                int tap_len = read(tap, tap_buffer, sizeof(tap_buffer));
                pthread_mutex_unlock(&tap_mutex);
                if(tap_len >= MIN_SIZE)
                {
                    /*
                    In reality, the contents of the tap buffer are preprocessed and the 
                    contents of another buffer are written to the serial 
                     */
                    pthread_mutex_lock(&serial_mutex);
                    int r = write(serial, tap_buffer, tap_len);
                    pthread_mutex_unlock(&serial_mutex);
                }
            }

        }
}
//T2 is completely analogous to the previous one

Since read and write are both performed in a critical section, would the mutex be automatically released if the thread were to be canceled?由于读写都是在临界区执行的,如果线程被取消,互斥锁会自动释放吗? And if not, how can I guarantee the release of the relative mutex?如果没有,我如何保证相关互斥锁的释放?

would the mutex be automatically released if the thread were to be canceled?如果要取消线程,互斥锁会自动释放吗?

No.不。

And if not, how can I guarantee the release of the relative mutex?如果没有,我如何保证相关互斥锁的释放?

The best way is to follow the first rule of pthread_cancel() : never call pthread_cancel() .最好的方法是遵循pthread_cancel()的第一条规则:永远不要调用pthread_cancel() Really, don't cancel threads.真的,不要取消线程。 It's bad news.这是个坏消息。

Another thing you could do is use pthread_setcancelstate() before and after the critical section to disable thread cancellation within.您可以做的另一件事是在关键部分之前和之后使用pthread_setcancelstate()来禁用线程取消。

But also, POSIX does have a facility for handling cleanup from thread cancellations.而且,POSIX 确实具有处理线程取消清理的功能。 You can use pthread_cleanup_push() to register a callback to perform the needed cleanup, and pthread_cleanup_pop() after the critical section to remove it again.您可以使用pthread_cleanup_push()注册回调以执行所需的清理,并在关键部分之后使用pthread_cleanup_pop()再次将其删除。 For this mechanism to adequately protect you, the thread's cancellation type must (always) be 'deferred', and you must take great care to consistently manage the cleanup handler stack.为了使这种机制充分保护您,线程的取消类型必须(始终)是“延迟的”,并且您必须非常小心地始终如一地管理清理处理程序堆栈。 If that sounds like a lot of work, that's because it is.如果这听起来像很多工作,那是因为它是。 Refer to the first rule of pthread_cancel() .请参阅pthread_cancel()的第一条规则。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM