#include <stdio.h>
#include <stdlib.h>
#include <poll.h>
#include <pthread.h>
#define offsetof(type, member) (size_t)&(((type *)(0))->member)
#define contain_of(ptr, type, member) (type *)((*(size_t *) &ptr) - offsetof(type, member)
typedef void (*fn_t)(int, char **);
struct list {
struct list *next;
};
struct list_cnt {
struct list root;
struct list **tail;
};
typedef struct task_queue {
int argc;
char **argv;
fn_t fn;
struct list node;
} task_queue_t;
static void put(struct list_cnt *head, struct list *node) {
node->next = NULL;
struct list **ptr = __sync_lock_test_and_set(&head->tail, &node->next);
*ptr = node;
}
static struct list *get(struct list_cnt *root) {
struct list *head = __sync_lock_test_and_set(&root->root.next, NULL);
if (head == NULL) {
return NULL;
}
struct list *next = head->next;
if (next != NULL) {
root->root.next = next;
head->next = head;
return head;
}
int b = __sync_bool_compare_and_swap(&root->tail, &head->next, &root->root.next);
if (b) {
head->next = head;
return head;
}
root->root.next = head;
return NULL;
}
void task(int argc, char **argv) {
printf("argc = %d, **argv = %d\n", argc, **argv);
free(*argv);
free(argv);
}
void test(struct list_cnt *head) {
int i = 0;
for (i = 0; i < 10; i++) {
task_queue_t *queue = malloc(sizeof(task_queue_t));
queue->argc = 1;
queue->argv = malloc(sizeof(int *));
*queue->argv = malloc(sizeof(int *));
**queue->argv = i;
queue->fn = task;
put(head, &queue->node);
}
}
void *do_task(void *arg) {
struct list_cnt *head = (struct list_cnt *)arg;
for (;;) {
struct list *tmp = NULL;
while ((tmp = get(head)) == NULL) {
poll(NULL, 0, 100);
}
task_queue_t *task = contain_of(tmp, task_queue_t, node);
task->fn(task->argc, task->argv);
free(task);
}
return NULL;
}
int main(int argc, char *argv[]) {
struct list_cnt head = {{NULL}, &(head.root.next)};
pthread_t thid;
pthread_create(&thid, NULL, do_task, &head);
test(&head);
for(;;);
return EXIT_SUCCESS;
}
单线程执行任务和无锁链表
最新推荐文章于 2023-10-14 20:02:37 发布