Libcurl - CURLSHOPT_LOCKFUNC - 如何使用它?
Libcurl - CURLSHOPT_LOCKFUNC - how to use it?
请告诉我使用选项 CURLSHOPT_LOCKFUNC ?
的细微差别
我找到了一个例子 here。
我不太明白,是否有一个互斥数组用于阻止对数据的访问?
--这是示例中的这部分代码:
static pthread_mutex_t lockarray[NUM_LOCKS]; Is it an array of mutexes ?
//.....
static void lock_cb(CURL *handle, curl_lock_data data,
curl_lock_access access, void *userptr)
{
(void)access;
(void)userptr;
(void)handle;
pthread_mutex_lock(&lockarray[data]);
}
也就是说,从这部分代码-我可以得出结论,不同的互斥量用于锁定 CURLSHOPT_LOCKFUNC ?
我不明白这是怎么回事?同步线程访问数据是否需要多个互斥量?
而且这部分代码也不清楚:
pthread_mutex_lock(&lockarray[data]);
data
是什么变量?
文档说:https://curl.se/libcurl/c/CURLSHOPT_LOCKFUNC.html
The data argument tells what kind of data libcurl wants to lock. Make
sure that the callback uses a different lock for each kind of data.
什么意思:“libcurl 想要锁定什么样的数据”??
看不懂
是的,代码使用了互斥体数组。
curl_lock_data
是在 curl.h
中定义的 enum
并指定 curl 使用锁的不同类型的数据:
/* Different data locks for a single share */
typedef enum {
CURL_LOCK_DATA_NONE = 0,
/* CURL_LOCK_DATA_SHARE is used internaly to say that
* the locking is just made to change the internal state of the share
* itself.
*/
CURL_LOCK_DATA_SHARE,
CURL_LOCK_DATA_COOKIE,
CURL_LOCK_DATA_DNS,
CURL_LOCK_DATA_SSL_SESSION,
CURL_LOCK_DATA_CONNECT,
CURL_LOCK_DATA_LAST
} curl_lock_data;
由于值是连续的,因此代码将它们用作数组的索引。
因此,例如,当多个线程访问共享 cookie 数据时,它们将 lock/unlock CURL_LOCK_DATA_COOKIE
互斥。
curl_lock_access
是 curl.h
中定义的另一个 enum
,它指定了获得给定锁的原因:
/* Different lock access types */
typedef enum {
CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */
CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */
CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */
CURL_LOCK_ACCESS_LAST /* never use */
} curl_lock_access;
这些原因之间的区别对于互斥体来说并不重要,互斥体只有独占访问的概念,这意味着一次只有一个线程可以持有锁。这就是代码未使用 access
参数的原因。
但是,其他类型的锁,例如 RW (reader/writer) 锁,确实有共享访问(即多个线程可以同时持有锁)与独占访问的概念。当多个线程想要访问相同的共享数据只是为了读取时,它们之间不阻塞是有意义的。只有当一个线程想要修改共享数据时,其他线程才会被阻止访问该数据,以读取或写入,直到修改完成。
例如:
const int NUM_LOCKS = CURL_LOCK_DATA_LAST + 1;
static pthread_rwlock_t lockarray[NUM_LOCKS];
...
static void lock_cb(CURL *handle, curl_lock_data data,
curl_lock_access access, void *userptr)
{
(void)handle;
(void)userptr;
switch (access) {
case CURL_LOCK_ACCESS_SHARED:
pthread_rwlock_rdlock(&lockarray[data]);
break;
case CURL_LOCK_ACCESS_ SINGLE:
pthread_rwlock_wrlock(&lockarray[data]);
break;
}
}
static void unlock_cb(CURL *handle, curl_lock_data data,
curl_lock_access access, void *userptr)
{
(void)handle;
(void)access;
(void)userptr;
pthread_rwlock_unlock(&lockarray[data]);
}
请告诉我使用选项 CURLSHOPT_LOCKFUNC ?
的细微差别我找到了一个例子 here。
我不太明白,是否有一个互斥数组用于阻止对数据的访问?
--这是示例中的这部分代码:
static pthread_mutex_t lockarray[NUM_LOCKS]; Is it an array of mutexes ?
//.....
static void lock_cb(CURL *handle, curl_lock_data data,
curl_lock_access access, void *userptr)
{
(void)access;
(void)userptr;
(void)handle;
pthread_mutex_lock(&lockarray[data]);
}
也就是说,从这部分代码-我可以得出结论,不同的互斥量用于锁定 CURLSHOPT_LOCKFUNC ?
我不明白这是怎么回事?同步线程访问数据是否需要多个互斥量?
而且这部分代码也不清楚:
pthread_mutex_lock(&lockarray[data]);
data
是什么变量?
文档说:https://curl.se/libcurl/c/CURLSHOPT_LOCKFUNC.html
The data argument tells what kind of data libcurl wants to lock. Make sure that the callback uses a different lock for each kind of data.
什么意思:“libcurl 想要锁定什么样的数据”??
看不懂
是的,代码使用了互斥体数组。
curl_lock_data
是在 curl.h
中定义的 enum
并指定 curl 使用锁的不同类型的数据:
/* Different data locks for a single share */
typedef enum {
CURL_LOCK_DATA_NONE = 0,
/* CURL_LOCK_DATA_SHARE is used internaly to say that
* the locking is just made to change the internal state of the share
* itself.
*/
CURL_LOCK_DATA_SHARE,
CURL_LOCK_DATA_COOKIE,
CURL_LOCK_DATA_DNS,
CURL_LOCK_DATA_SSL_SESSION,
CURL_LOCK_DATA_CONNECT,
CURL_LOCK_DATA_LAST
} curl_lock_data;
由于值是连续的,因此代码将它们用作数组的索引。
因此,例如,当多个线程访问共享 cookie 数据时,它们将 lock/unlock CURL_LOCK_DATA_COOKIE
互斥。
curl_lock_access
是 curl.h
中定义的另一个 enum
,它指定了获得给定锁的原因:
/* Different lock access types */
typedef enum {
CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */
CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */
CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */
CURL_LOCK_ACCESS_LAST /* never use */
} curl_lock_access;
这些原因之间的区别对于互斥体来说并不重要,互斥体只有独占访问的概念,这意味着一次只有一个线程可以持有锁。这就是代码未使用 access
参数的原因。
但是,其他类型的锁,例如 RW (reader/writer) 锁,确实有共享访问(即多个线程可以同时持有锁)与独占访问的概念。当多个线程想要访问相同的共享数据只是为了读取时,它们之间不阻塞是有意义的。只有当一个线程想要修改共享数据时,其他线程才会被阻止访问该数据,以读取或写入,直到修改完成。
例如:
const int NUM_LOCKS = CURL_LOCK_DATA_LAST + 1;
static pthread_rwlock_t lockarray[NUM_LOCKS];
...
static void lock_cb(CURL *handle, curl_lock_data data,
curl_lock_access access, void *userptr)
{
(void)handle;
(void)userptr;
switch (access) {
case CURL_LOCK_ACCESS_SHARED:
pthread_rwlock_rdlock(&lockarray[data]);
break;
case CURL_LOCK_ACCESS_ SINGLE:
pthread_rwlock_wrlock(&lockarray[data]);
break;
}
}
static void unlock_cb(CURL *handle, curl_lock_data data,
curl_lock_access access, void *userptr)
{
(void)handle;
(void)access;
(void)userptr;
pthread_rwlock_unlock(&lockarray[data]);
}